Back to index

salome-geom  6.5.0
orientation.py
Go to the documentation of this file.
00001 # -*- coding: utf-8 -*-
00002 #
00003 # Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00004 #
00005 # This library is free software; you can redistribute it and/or
00006 # modify it under the terms of the GNU Lesser General Public
00007 # License as published by the Free Software Foundation; either
00008 # version 2.1 of the License.
00009 #
00010 # This library is distributed in the hope that it will be useful,
00011 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 # Lesser General Public License for more details.
00014 #
00015 # You should have received a copy of the GNU Lesser General Public
00016 # License along with this library; if not, write to the Free Software
00017 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00018 #
00019 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00020 #
00021 """
00022 This module is used to compute the orientation of the different parts in a
00023 structural element and to build the corresponding markers (trihedrons).
00024 """
00025 
00026 import math
00027 
00028 from salome.kernel.logger import Logger
00029 from salome.kernel import termcolor
00030 logger = Logger("__PAL_GEOM__.structelem.orientation", color = termcolor.RED)
00031 
00032 
00033 class Orientation1D:
00034     """
00035     This class is used to compute the orientation of 1D elements and to build
00036     the corresponding markers.
00037     """
00038     
00039     def __init__(self):
00040         self.geom = None
00041         self._vectorYCoords = None
00042         self._angle = 0.0
00043 
00044     def __repr__(self):
00045         reprdict = self.__dict__.copy()
00046         del reprdict["geom"]
00047         return '%s(%s)' % (self.__class__.__name__, reprdict)
00048 
00049     def addParams(self, params):
00050         """
00051         Add orientation parameters. `params` is a dictionary containing one or
00052         several orientation parameters. The valid parameters are:
00053 
00054         * "VECT_Y": Triplet defining the local Y axis (the X axis is the
00055           main direction of the 1D element).
00056         * "ANGL_VRIL": Angle of rotation along the X axis to define the local
00057           coordinate system.
00058         
00059         The parameters can be specified several times. In this case, only the
00060         first "VECT_Y" is taken into account, and the values of "ANGL_VRIL"
00061         are added to obtain the total rotation angle.
00062         """
00063         mydict = params.copy()
00064         if mydict.has_key("VECT_Y"):
00065             newVecCoords = mydict.pop("VECT_Y")
00066             if self._vectorYCoords is None:
00067                 logger.debug("Setting orientation vector Y to %s" %
00068                              str(newVecCoords))
00069                 self._vectorYCoords = newVecCoords
00070             else:
00071                 logger.warning('Orientation parameter "VECT_Y" is specified '
00072                                'several times for the same mesh group, vector'
00073                                ' %s will be used' % str(self._vectorYCoords))
00074         if mydict.has_key("ANGL_VRIL"):
00075             newAngle = mydict.pop("ANGL_VRIL")
00076             self._angle += newAngle
00077             logger.debug("Adding angle %f to orientation, new angle is %f." %
00078                          (newAngle, self._angle))
00079         if len(mydict) > 0:
00080             logger.warning("Invalid orientation parameter(s) (ignored): %s" %
00081                            str(mydict))
00082 
00083     def _getDefaultVecYZ(self, center, vecX):
00084         """
00085         Get the vectors Y and Z for the default LCS, that use the main
00086         direction of the 1D object as the local X axis and the global Z axis
00087         to determine the local Z axis.
00088         """
00089         xPoint = self.geom.MakeTranslationVector(center, vecX)
00090         givenVecZ = self.geom.MakeVectorDXDYDZ(0.0, 0.0, 1.0)
00091         angle = self.geom.GetAngleRadians(vecX, givenVecZ)
00092         if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
00093             logger.warning("Beam X axis is colinear to absolute Z axis. "
00094                            "Absolute X axis will be used to determine "
00095                            "local Z axis.")
00096             givenVecZ = self.geom.MakeVectorDXDYDZ(1.0, 0.0, 0.0)
00097         zPoint = self.geom.MakeTranslationVector(center, givenVecZ)
00098         locPlaneZX = self.geom.MakePlaneThreePnt(center, zPoint, xPoint, 1.0)
00099         locY = self.geom.GetNormal(locPlaneZX)
00100         yPoint = self.geom.MakeTranslationVector(center, locY)
00101         locPlaneXY = self.geom.MakePlaneThreePnt(center, xPoint, yPoint, 1.0)
00102         locZ = self.geom.GetNormal(locPlaneXY)
00103         return (locY, locZ)
00104 
00105     def buildMarker(self, geom, center, vecX):
00106         """
00107         Create a marker with origin `center` and X axis `vecX`. `geom` is the
00108         pseudo-geompy object used to build the geometric shapes.
00109         """
00110         (locY, locZ) = self.getVecYZ(geom, center, vecX)
00111         marker = geom.MakeMarkerPntTwoVec(center, vecX, locY)
00112         return marker
00113 
00114     def getVecYZ(self, geom, center, vecX):
00115         """
00116         Get the vectors Y and Z for the LCS with origin `center` and X axis
00117         `vecX`. `geom` is the pseudo-geompy object used to build the geometric
00118         shapes.
00119         """
00120         self.geom = geom
00121         locY = None
00122         locZ = None
00123         if self._vectorYCoords is None:
00124             (locY, locZ) = self._getDefaultVecYZ(center, vecX)
00125         else:
00126             xPoint = self.geom.MakeTranslationVector(center, vecX)
00127             givenLocY = self.geom.MakeVectorDXDYDZ(self._vectorYCoords[0],
00128                                                    self._vectorYCoords[1],
00129                                                    self._vectorYCoords[2])
00130             angle = self.geom.GetAngleRadians(vecX, givenLocY)
00131             if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
00132                 logger.warning("Vector Y is colinear to the beam X axis, "
00133                                "using default LCS.")
00134                 (locY, locZ) = self._getDefaultVecYZ(center, vecX)
00135             else:
00136                 yPoint = self.geom.MakeTranslationVector(center, givenLocY)
00137                 locPlaneXY = self.geom.MakePlaneThreePnt(center, xPoint,
00138                                                          yPoint, 1.0)
00139                 locZ = self.geom.GetNormal(locPlaneXY)
00140                 zPoint = self.geom.MakeTranslationVector(center, locZ)
00141                 locPlaneZX = self.geom.MakePlaneThreePnt(center, zPoint,
00142                                                          xPoint, 1.0)
00143                 locY = self.geom.GetNormal(locPlaneZX)
00144 
00145         if self._angle != 0.0:
00146             angleRad = math.radians(self._angle)
00147             locY = self.geom.Rotate(locY, vecX, angleRad)
00148             locZ = self.geom.Rotate(locZ, vecX, angleRad)
00149 
00150         return (locY, locZ)
00151 
00152 
00153 class Orientation2D:
00154     """
00155     This class is used to compute the orientation of 2D elements and to build
00156     the corresponding markers. Angles `alpha` and `beta` are used to determine
00157     the local coordinate system for the 2D element. If `vect` is not
00158     :const:`None`, it is used instead of `alpha` and `beta`.
00159     """
00160 
00161     def __init__(self, alpha, beta, vect):
00162         self.geom = None
00163         self._alpha = alpha
00164         self._beta = beta
00165         self._vect = vect
00166 
00167     def __repr__(self):
00168         reprdict = self.__dict__.copy()
00169         del reprdict["geom"]
00170         return '%s(%s)' % (self.__class__.__name__, reprdict)
00171 
00172     def _buildDefaultMarker(self, center, normal, warnings = True):
00173         """
00174         Create the default marker, that use the normal vector of the 2D object
00175         as the local Z axis and the global X axis to determine the local X
00176         axis. `warnings` can be used to enable or disable the logging of
00177         warning messages.
00178         """
00179         marker = None
00180         globalVecX = self.geom.MakeVectorDXDYDZ(1.0, 0.0, 0.0)
00181         angle = self.geom.GetAngleRadians(normal, globalVecX)
00182         if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
00183             if warnings:
00184                 logger.warning("Face normal is colinear to absolute X axis. "
00185                                "Absolute Y axis will be used to determine "
00186                                "local X axis.")
00187             globalVecY = self.geom.MakeVectorDXDYDZ(0.0, 1.0, 0.0)
00188             marker = self._buildMarkerRefVecX(center, normal, globalVecY)
00189         else:
00190             marker = self._buildMarkerRefVecX(center, normal, globalVecX)
00191         return marker
00192 
00193     def _buildMarkerRefVecX(self, center, normal, refVecX):
00194         """
00195         Create a marker using `normal` as Z axis and `refVecX` to determine
00196         the X axis.
00197         """
00198         xPoint = self.geom.MakeTranslationVector(center, refVecX)
00199         zPoint = self.geom.MakeTranslationVector(center, normal)
00200         locPlaneZX = self.geom.MakePlaneThreePnt(center, zPoint, xPoint, 1.0)
00201         locY = self.geom.GetNormal(locPlaneZX)
00202         yPoint = self.geom.MakeTranslationVector(center, locY)
00203         locPlaneYZ = self.geom.MakePlaneThreePnt(center, yPoint, zPoint, 1.0)
00204         locX = self.geom.GetNormal(locPlaneYZ)
00205         marker = self.geom.MakeMarkerPntTwoVec(center, locX, locY)
00206         return marker
00207 
00208     def buildMarker(self, geom, center, normal, warnings = True):
00209         """
00210         Create a marker with origin `center` and `normal` as Z axis. The other
00211         axes are computed using the parameters alpha and beta of the
00212         Orientation2D instance. `geom` is the pseudo-geompy object used to
00213         build the geometric shapes. `warnings` can be used to enable or
00214         disable the logging of warning messages.
00215         """
00216         self.geom = geom
00217         marker = None
00218         refVecX = None
00219         if self._vect is not None:
00220             # Using vector parameter
00221             if abs(self._vect[0]) <= 1e-7 and abs(self._vect[1]) <= 1e-7 and \
00222                                               abs(self._vect[2]) <= 1e-7:
00223                 if warnings:
00224                     logger.warning("Vector too small: %s, using default LCS" %
00225                                    self._vect)
00226             else:
00227                 refVecX = self.geom.MakeVectorDXDYDZ(self._vect[0],
00228                                                      self._vect[1],
00229                                                      self._vect[2])
00230         elif self._alpha is not None and self._beta is not None:
00231             # Using alpha and beta angles
00232             alphaRad = math.radians(self._alpha)
00233             betaRad = math.radians(self._beta)
00234             if abs(alphaRad) <= 1e-7 and abs(betaRad) <= 1e-7:
00235                 if warnings:
00236                     logger.warning("Angles too small: (%g, %g), using "
00237                                    "default LCS" % (self._alpha, self._beta))
00238             else:
00239                 # rotate global CS with angles alpha and beta
00240                 refVecX = self.geom.MakeVectorDXDYDZ(1.0, 0.0, 0.0)
00241                 refVecY = self.geom.MakeVectorDXDYDZ(0.0, 1.0, 0.0)
00242                 globalVecZ = self.geom.MakeVectorDXDYDZ(0.0, 0.0, 1.0)
00243                 if abs(alphaRad) > 1e-7:
00244                     refVecX = self.geom.Rotate(refVecX, globalVecZ, alphaRad)
00245                     refVecY = self.geom.Rotate(refVecY, globalVecZ, alphaRad)
00246                 if abs(betaRad) > 1e-7:
00247                     refVecX = self.geom.Rotate(refVecX, refVecY, betaRad)
00248     
00249         if refVecX is not None:
00250             # build local coordinate system
00251             angle = self.geom.GetAngleRadians(normal, refVecX)
00252             if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
00253                 if warnings:
00254                     logger.warning("Face normal is colinear to the reference "
00255                                    "X axis, using default LCS.")
00256             else:
00257                 marker = self._buildMarkerRefVecX(center, normal, refVecX)
00258 
00259         if marker is None:
00260             marker = self._buildDefaultMarker(center, normal, warnings)
00261 
00262         return marker