mirror of
https://git.salome-platform.org/gitpub/modules/geom.git
synced 2025-04-05 12:28:26 +05:00
262 lines
11 KiB
Python
262 lines
11 KiB
Python
# -*- coding: utf-8 -*-
|
|
#
|
|
# Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
|
|
#
|
|
# This library is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU Lesser General Public
|
|
# License as published by the Free Software Foundation; either
|
|
# version 2.1 of the License.
|
|
#
|
|
# This library is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
# Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public
|
|
# License along with this library; if not, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
#
|
|
# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
|
#
|
|
"""
|
|
This module is used to compute the orientation of the different parts in a
|
|
structural element and to build the corresponding markers (trihedrons).
|
|
"""
|
|
|
|
import math
|
|
|
|
from salome.kernel.logger import Logger
|
|
from salome.kernel import termcolor
|
|
logger = Logger("salome.geom.structelem.orientation", color = termcolor.RED)
|
|
|
|
|
|
class Orientation1D:
|
|
"""
|
|
This class is used to compute the orientation of 1D elements and to build
|
|
the corresponding markers.
|
|
"""
|
|
|
|
def __init__(self):
|
|
self.geom = None
|
|
self._vectorYCoords = None
|
|
self._angle = 0.0
|
|
|
|
def __repr__(self):
|
|
reprdict = self.__dict__.copy()
|
|
del reprdict["geom"]
|
|
return '%s(%s)' % (self.__class__.__name__, reprdict)
|
|
|
|
def addParams(self, params):
|
|
"""
|
|
Add orientation parameters. `params` is a dictionary containing one or
|
|
several orientation parameters. The valid parameters are:
|
|
|
|
* "VECT_Y": Triplet defining the local Y axis (the X axis is the
|
|
main direction of the 1D element).
|
|
* "ANGL_VRIL": Angle of rotation along the X axis to define the local
|
|
coordinate system.
|
|
|
|
The parameters can be specified several times. In this case, only the
|
|
last "VECT_Y" or "ANGL_VRIL" is taken into account.
|
|
"""
|
|
if self._vectorYCoords is not None or self._angle != 0.0:
|
|
logger.warning('Orientation parameters are specified several '
|
|
'times for the same mesh group, only the last '
|
|
'parameter will be used')
|
|
mydict = params.copy()
|
|
if mydict.has_key("VECT_Y"):
|
|
newVecCoords = mydict.pop("VECT_Y")
|
|
logger.debug("Setting orientation vector Y to %s" %
|
|
str(newVecCoords))
|
|
self._vectorYCoords = newVecCoords
|
|
self._angle = 0.0
|
|
if mydict.has_key("ANGL_VRIL"):
|
|
newAngle = mydict.pop("ANGL_VRIL")
|
|
logger.debug("Setting orientation angle to %f" % newAngle)
|
|
self._angle = newAngle
|
|
self._vectorYCoords = None
|
|
if len(mydict) > 0:
|
|
logger.warning("Invalid orientation parameter(s) (ignored): %s" %
|
|
str(mydict))
|
|
|
|
def _getDefaultVecYZ(self, center, vecX):
|
|
"""
|
|
Get the vectors Y and Z for the default LCS, that use the main
|
|
direction of the 1D object as the local X axis and the global Z axis
|
|
to determine the local Z axis.
|
|
"""
|
|
xPoint = self.geom.MakeTranslationVector(center, vecX)
|
|
givenVecZ = self.geom.MakeVectorDXDYDZ(0.0, 0.0, 1.0)
|
|
angle = self.geom.GetAngleRadians(vecX, givenVecZ)
|
|
if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
|
|
logger.warning("Beam X axis is colinear to absolute Z axis. "
|
|
"Absolute X axis will be used to determine "
|
|
"local Z axis.")
|
|
givenVecZ = self.geom.MakeVectorDXDYDZ(1.0, 0.0, 0.0)
|
|
zPoint = self.geom.MakeTranslationVector(center, givenVecZ)
|
|
locPlaneZX = self.geom.MakePlaneThreePnt(center, zPoint, xPoint, 1.0)
|
|
locY = self.geom.GetNormal(locPlaneZX)
|
|
yPoint = self.geom.MakeTranslationVector(center, locY)
|
|
locPlaneXY = self.geom.MakePlaneThreePnt(center, xPoint, yPoint, 1.0)
|
|
locZ = self.geom.GetNormal(locPlaneXY)
|
|
return (locY, locZ)
|
|
|
|
def buildMarker(self, geom, center, vecX):
|
|
"""
|
|
Create a marker with origin `center` and X axis `vecX`. `geom` is the
|
|
pseudo-geompy object used to build the geometric shapes.
|
|
"""
|
|
(locY, locZ) = self.getVecYZ(geom, center, vecX)
|
|
marker = geom.MakeMarkerPntTwoVec(center, vecX, locY)
|
|
return marker
|
|
|
|
def getVecYZ(self, geom, center, vecX):
|
|
"""
|
|
Get the vectors Y and Z for the LCS with origin `center` and X axis
|
|
`vecX`. `geom` is the pseudo-geompy object used to build the geometric
|
|
shapes.
|
|
"""
|
|
self.geom = geom
|
|
locY = None
|
|
locZ = None
|
|
if self._vectorYCoords is None:
|
|
(locY, locZ) = self._getDefaultVecYZ(center, vecX)
|
|
else:
|
|
xPoint = self.geom.MakeTranslationVector(center, vecX)
|
|
givenLocY = self.geom.MakeVectorDXDYDZ(self._vectorYCoords[0],
|
|
self._vectorYCoords[1],
|
|
self._vectorYCoords[2])
|
|
angle = self.geom.GetAngleRadians(vecX, givenLocY)
|
|
if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
|
|
logger.warning("Vector Y is colinear to the beam X axis, "
|
|
"using default LCS.")
|
|
(locY, locZ) = self._getDefaultVecYZ(center, vecX)
|
|
else:
|
|
yPoint = self.geom.MakeTranslationVector(center, givenLocY)
|
|
locPlaneXY = self.geom.MakePlaneThreePnt(center, xPoint,
|
|
yPoint, 1.0)
|
|
locZ = self.geom.GetNormal(locPlaneXY)
|
|
zPoint = self.geom.MakeTranslationVector(center, locZ)
|
|
locPlaneZX = self.geom.MakePlaneThreePnt(center, zPoint,
|
|
xPoint, 1.0)
|
|
locY = self.geom.GetNormal(locPlaneZX)
|
|
|
|
if self._angle != 0.0:
|
|
angleRad = math.radians(self._angle)
|
|
locY = self.geom.Rotate(locY, vecX, angleRad)
|
|
locZ = self.geom.Rotate(locZ, vecX, angleRad)
|
|
|
|
return (locY, locZ)
|
|
|
|
|
|
class Orientation2D:
|
|
"""
|
|
This class is used to compute the orientation of 2D elements and to build
|
|
the corresponding markers. Angles `alpha` and `beta` are used to determine
|
|
the local coordinate system for the 2D element. If `vect` is not
|
|
:const:`None`, it is used instead of `alpha` and `beta`.
|
|
"""
|
|
|
|
def __init__(self, alpha, beta, vect):
|
|
self.geom = None
|
|
self._alpha = alpha
|
|
self._beta = beta
|
|
self._vect = vect
|
|
|
|
def __repr__(self):
|
|
reprdict = self.__dict__.copy()
|
|
del reprdict["geom"]
|
|
return '%s(%s)' % (self.__class__.__name__, reprdict)
|
|
|
|
def _buildDefaultMarker(self, center, normal, warnings = True):
|
|
"""
|
|
Create the default marker, that use the normal vector of the 2D object
|
|
as the local Z axis and the global X axis to determine the local X
|
|
axis. `warnings` can be used to enable or disable the logging of
|
|
warning messages.
|
|
"""
|
|
marker = None
|
|
globalVecX = self.geom.MakeVectorDXDYDZ(1.0, 0.0, 0.0)
|
|
angle = self.geom.GetAngleRadians(normal, globalVecX)
|
|
if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
|
|
if warnings:
|
|
logger.warning("Face normal is colinear to absolute X axis. "
|
|
"Absolute Y axis will be used to determine "
|
|
"local X axis.")
|
|
globalVecY = self.geom.MakeVectorDXDYDZ(0.0, 1.0, 0.0)
|
|
marker = self._buildMarkerRefVecX(center, normal, globalVecY)
|
|
else:
|
|
marker = self._buildMarkerRefVecX(center, normal, globalVecX)
|
|
return marker
|
|
|
|
def _buildMarkerRefVecX(self, center, normal, refVecX):
|
|
"""
|
|
Create a marker using `normal` as Z axis and `refVecX` to determine
|
|
the X axis.
|
|
"""
|
|
xPoint = self.geom.MakeTranslationVector(center, refVecX)
|
|
zPoint = self.geom.MakeTranslationVector(center, normal)
|
|
locPlaneZX = self.geom.MakePlaneThreePnt(center, zPoint, xPoint, 1.0)
|
|
locY = self.geom.GetNormal(locPlaneZX)
|
|
yPoint = self.geom.MakeTranslationVector(center, locY)
|
|
locPlaneYZ = self.geom.MakePlaneThreePnt(center, yPoint, zPoint, 1.0)
|
|
locX = self.geom.GetNormal(locPlaneYZ)
|
|
marker = self.geom.MakeMarkerPntTwoVec(center, locX, locY)
|
|
return marker
|
|
|
|
def buildMarker(self, geom, center, normal, warnings = True):
|
|
"""
|
|
Create a marker with origin `center` and `normal` as Z axis. The other
|
|
axes are computed using the parameters alpha and beta of the
|
|
Orientation2D instance. `geom` is the pseudo-geompy object used to
|
|
build the geometric shapes. `warnings` can be used to enable or
|
|
disable the logging of warning messages.
|
|
"""
|
|
self.geom = geom
|
|
marker = None
|
|
refVecX = None
|
|
if self._vect is not None:
|
|
# Using vector parameter
|
|
if abs(self._vect[0]) <= 1e-7 and abs(self._vect[1]) <= 1e-7 and \
|
|
abs(self._vect[2]) <= 1e-7:
|
|
if warnings:
|
|
logger.warning("Vector too small: %s, using default LCS" %
|
|
self._vect)
|
|
else:
|
|
refVecX = self.geom.MakeVectorDXDYDZ(self._vect[0],
|
|
self._vect[1],
|
|
self._vect[2])
|
|
elif self._alpha is not None and self._beta is not None:
|
|
# Using alpha and beta angles
|
|
alphaRad = math.radians(self._alpha)
|
|
betaRad = math.radians(self._beta)
|
|
if abs(alphaRad) <= 1e-7 and abs(betaRad) <= 1e-7:
|
|
if warnings:
|
|
logger.warning("Angles too small: (%g, %g), using "
|
|
"default LCS" % (self._alpha, self._beta))
|
|
else:
|
|
# rotate global CS with angles alpha and beta
|
|
refVecX = self.geom.MakeVectorDXDYDZ(1.0, 0.0, 0.0)
|
|
refVecY = self.geom.MakeVectorDXDYDZ(0.0, 1.0, 0.0)
|
|
globalVecZ = self.geom.MakeVectorDXDYDZ(0.0, 0.0, 1.0)
|
|
if abs(alphaRad) > 1e-7:
|
|
refVecX = self.geom.Rotate(refVecX, globalVecZ, alphaRad)
|
|
refVecY = self.geom.Rotate(refVecY, globalVecZ, alphaRad)
|
|
if abs(betaRad) > 1e-7:
|
|
refVecX = self.geom.Rotate(refVecX, refVecY, betaRad)
|
|
|
|
if refVecX is not None:
|
|
# build local coordinate system
|
|
angle = self.geom.GetAngleRadians(normal, refVecX)
|
|
if abs(angle) < 1e-7 or abs(angle - math.pi) < 1e-7:
|
|
if warnings:
|
|
logger.warning("Face normal is colinear to the reference "
|
|
"X axis, using default LCS.")
|
|
else:
|
|
marker = self._buildMarkerRefVecX(center, normal, refVecX)
|
|
|
|
if marker is None:
|
|
marker = self._buildDefaultMarker(center, normal, warnings)
|
|
|
|
return marker
|