From 86007b0b5d945f2aeaadd555b9913df0b57790f9 Mon Sep 17 00:00:00 2001 From: eap Date: Wed, 27 Jan 2021 13:10:14 +0300 Subject: [PATCH 1/4] bos #20543 EDF 22638 - hyperpatch with CADSurf A nice solution for pb of dealing with SHAPERSTUDY objects has been found --- src/SMESH_SWIG/smeshBuilder.py | 22 ++++++++++-------- src/SMESH_SWIG/smesh_algorithm.py | 38 ++----------------------------- 2 files changed, 14 insertions(+), 46 deletions(-) diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index c99e95821..7bdc59eb4 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -1651,7 +1651,17 @@ class Mesh(metaclass = MeshMeta): #self.mesh.Register() self.geom = self.mesh.GetShapeToMesh() if self.geom: - self.geompyD = self.geom.GetGen() + self.geompyD = None + try: + so = salome.ObjectToSObject( self.geom ) + comp = so.GetFatherComponent() + if comp.ComponentDataType() == "SHAPERSTUDY": + import shaperBuilder + self.geompyD = shaperBuilder.New() + except: + pass + if not self.geompyD: + self.geompyD = self.geom.GetGen() pass pass @@ -2642,15 +2652,7 @@ class Mesh(metaclass = MeshMeta): elif tgeo == "SOLID" or tgeo == "COMPSOLID": typ = VOLUME elif tgeo == "COMPOUND": - try: - sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"]) - except: - # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of - # simplification of access in geomBuilder: omniORB.registerObjref - from SHAPERSTUDY_utils import getEngine - gen = getEngine() - if gen: - sub = gen.GetIShapesOperations().ExtractSubShapes(shape, self.geompyD.ShapeType["SHAPE"], False) + sub = self.geompyD.SubShapeAll( shape, self.geompyD.ShapeType["SHAPE"]) if not sub: raise ValueError("_groupTypeFromShape(): empty geometric group or compound '%s'" % GetName(shape)) return self._groupTypeFromShape( sub[0] ) diff --git a/src/SMESH_SWIG/smesh_algorithm.py b/src/SMESH_SWIG/smesh_algorithm.py index e9867dc4e..62495cc49 100644 --- a/src/SMESH_SWIG/smesh_algorithm.py +++ b/src/SMESH_SWIG/smesh_algorithm.py @@ -340,20 +340,9 @@ class Mesh_Algorithm: if faces and isinstance( faces[0], geomBuilder.GEOM._objref_GEOM_Object ): faceIDs = [] for shape in faces: - try: - ff = self.mesh.geompyD.SubShapeAll( shape, self.mesh.geompyD.ShapeType["FACE"] ) - for f in ff: + ff = self.mesh.geompyD.SubShapeAll( shape, self.mesh.geompyD.ShapeType["FACE"] ) + for f in ff: faceIDs.append( self.mesh.geompyD.GetSubShapeID(self.mesh.geom, f)) - except: - # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of - # simplification of access in geomBuilder: omniORB.registerObjref - from SHAPERSTUDY_utils import getEngine - gen = getEngine() - if gen: - aShapeOp = gen.GetIShapesOperations() - ff = aShapeOp.ExtractSubShapes( shape, self.mesh.geompyD.ShapeType["FACE"], False) - for f in ff: - faceIDs.append( aShapeOp.GetSubShapeIndex( self.mesh.geom, f )) faces = faceIDs hyp = self.Hypothesis("ViscousLayers", [thickness, numberOfLayers, stretchFactor, faces, isFacesToIgnore], @@ -403,20 +392,9 @@ class Mesh_Algorithm: if edges and isinstance( edges[0], geomBuilder.GEOM._objref_GEOM_Object ): edgeIDs = [] for shape in edges: - try: ee = self.mesh.geompyD.SubShapeAll( shape, self.mesh.geompyD.ShapeType["EDGE"]) for e in ee: edgeIDs.append( self.mesh.geompyD.GetSubShapeID( self.mesh.geom, e )) - except: - # try to get the SHAPERSTUDY engine directly, because GetGen does not work because of - # simplification of access in geomBuilder: omniORB.registerObjref - from SHAPERSTUDY_utils import getEngine - gen = getEngine() - if gen: - aShapeOp = gen.GetIShapesOperations() - ee = aShapeOp.ExtractSubShapes( shape, self.mesh.geompyD.ShapeType["EDGE"], False) - for e in ee: - edgeIDs.append( aShapeOp.GetSubShapeIndex( self.mesh.geom, e )) edges = edgeIDs hyp = self.Hypothesis("ViscousLayers2D", [thickness, numberOfLayers, stretchFactor, edges, isEdgesToIgnore], @@ -440,18 +418,6 @@ class Mesh_Algorithm: for i in reverseList: if isinstance( i, int ): s = geompy.GetSubShape(self.mesh.geom, [i]) - - #bos #20082 begin: - if s is None and type(self.geom) != geomBuilder.GEOM._objref_GEOM_Object: - # try to get the SHAPERSTUDY engine directly, as GetGen does not work because of - # simplification of access in geomBuilder: omniORB.registerObjref - from SHAPERSTUDY_utils import getEngine - gen = getEngine() - if gen: - aShapeOp = gen.GetIShapesOperations() - s = aShapeOp.GetSubShape(self.mesh.geom, i) - #bos #20082 end - if s.GetShapeType() != geomBuilder.GEOM.EDGE: raise TypeError("Not EDGE index given") resList.append( i ) From 374031c17eaff49e84ed4d627f17e1d4c57a41e0 Mon Sep 17 00:00:00 2001 From: eap Date: Wed, 27 Jan 2021 16:48:04 +0300 Subject: [PATCH 2/4] bos #20640 EDF 22800 - Adding 3D --- src/SMESHUtils/SMESH_MeshAlgos.cxx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/SMESHUtils/SMESH_MeshAlgos.cxx b/src/SMESHUtils/SMESH_MeshAlgos.cxx index 3bc48ff24..7a4a0a481 100644 --- a/src/SMESHUtils/SMESH_MeshAlgos.cxx +++ b/src/SMESHUtils/SMESH_MeshAlgos.cxx @@ -688,6 +688,9 @@ bool SMESH_ElementSearcherImpl::getIntersParamOnLine(const gp_Lin& lin GC_MakeSegment edge( SMESH_TNodeXYZ( face->GetNode( i )), SMESH_TNodeXYZ( face->GetNode( (i+1)%nbNodes) )); anExtCC.Init( lineCurve, edge.Value() ); + if ( !anExtCC.Extrema().IsDone() || + anExtCC.Extrema().IsParallel() ) + continue; if ( anExtCC.NbExtrema() > 0 && anExtCC.LowerDistance() <= tol) { Standard_Real pl, pe; From bca8bf9ddb0a6f813460a38d0e718e3aa2a00082 Mon Sep 17 00:00:00 2001 From: Christophe Bourcier Date: Wed, 27 Jan 2021 11:31:41 +0100 Subject: [PATCH 3/4] Fix polyhedron on penta Add a test on all kinds of elements --- .../examples/test_polyhedron_per_solid.py | 128 ++++++++++++++++++ doc/salome/examples/tests.set | 1 + .../StdMeshers_PolyhedronPerSolid_3D.cxx | 3 + 3 files changed, 132 insertions(+) create mode 100644 doc/salome/examples/test_polyhedron_per_solid.py diff --git a/doc/salome/examples/test_polyhedron_per_solid.py b/doc/salome/examples/test_polyhedron_per_solid.py new file mode 100644 index 000000000..36fa51026 --- /dev/null +++ b/doc/salome/examples/test_polyhedron_per_solid.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python + +import sys +import salome + +salome.salome_init() + +### +### GEOM component +### + +import GEOM +from salome.geom import geomBuilder +import math +import SALOMEDS + + +geompy = geomBuilder.New() + +## Creates a polygon given its centre, external radius and number of sides +def makePolygon(p_centre, radius, nb_sides, theName=""): + points = [] + x, y, z = geompy.PointCoordinates(p_centre) + for i in range(nb_sides): + angle = i*2*math.pi/nb_sides + p = geompy.MakeVertex(x+radius*math.cos(angle), y+radius*math.sin(angle), 0) + points.append(p) + wire = geompy.MakePolyline(points, True) + face = geompy.MakeFace(wire, 1) + if theName: + geompy.addToStudy(face, theName) + return face + +## Creates a solid by adding a vertex on its top +def makeSummitSolid(face, height, theName=""): + p_cdg = geompy.MakeCDG(face) + p_top = geompy.MakeTranslation(p_cdg, 0, 0, height) + edges = geompy.SubShapeAll(face, geompy.ShapeType["EDGE"]) + faces = [face] + for edge in edges: + p1, p2 = geompy.SubShapeAll(edge, geompy.ShapeType["VERTEX"]) + wire = geompy.MakePolyline([p1, p2, p_top], True) + face = geompy.MakeFace(wire, 1) + faces.append(face) + shell = geompy.MakeShell(faces) + solid = geompy.MakeSolid(shell) + if theName: + geompy.addToStudy(solid, theName) + return solid + +O = geompy.MakeVertex(0, 0, 0) +OX = geompy.MakeVectorDXDYDZ(1, 0, 0) +OY = geompy.MakeVectorDXDYDZ(0, 1, 0) +OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) +geompy.addToStudy( O, 'O' ) +geompy.addToStudy( OX, 'OX' ) +geompy.addToStudy( OY, 'OY' ) +geompy.addToStudy( OZ, 'OZ' ) + +height = 0.5 + +triangle = makePolygon(O, 1, 3, "triangle") + +P1 = geompy.MakeVertex(2, 0, 0) +quadrangle = makePolygon(P1, 1, 4, "quadrangle") + +P2 = geompy.MakeVertex(4, 0, 0) +pentagon = makePolygon(P2, 1, 5, "pentagon") + +P3 = geompy.MakeVertex(6, 0, 0) +hexagon = makePolygon(P3, 1, 6, "hexagon") + +P4 = geompy.MakeVertex(8, 0, 0) +heptagon = makePolygon(P4, 1, 7, "heptagon") + +P5 = geompy.MakeVertex(10, 0, 0) +octagon = makePolygon(P5, 1, 7, "octagon") + +polygons = [triangle, quadrangle, pentagon, hexagon, heptagon, octagon] +polyhedrons = [] +for polygon in polygons: + name = polygon.GetName() + polygon_extruded = geompy.MakePrismVecH(polygon, OZ, height, theName="%s_prism"%name) + polygon_summit = makeSummitSolid(polygon, -height, theName="%s_summit"%name) + polyhedrons += [polygon_extruded, polygon_summit] + +solids = geompy.MakeCompound(polyhedrons, theName="solids") + + +### +### SMESH component +### + +import SMESH, SALOMEDS +from salome.smesh import smeshBuilder + +smesh = smeshBuilder.New() + +Mesh_1 = smesh.Mesh(solids) +Regular_1D = Mesh_1.Segment() +Number_of_Segments_1 = Regular_1D.NumberOfSegments(1) +PolygonPerFace_2D = Mesh_1.Polygon() +PolyhedronPerSolid_3D = Mesh_1.Polyhedron() + +ok = Mesh_1.Compute() + +if not ok: + raise Exception("Error when computing Mesh") + +# check volumes +vol_geom = geompy.BasicProperties(solids)[2] +vol_mesh = Mesh_1.GetVolume() + +assert abs(vol_geom - vol_mesh) < 1e-12 + +assert Mesh_1.NbVolumes() == 12 + +# check type of elements +assert Mesh_1.NbTetras() == 1 +assert Mesh_1.NbHexas() == 1 +assert Mesh_1.NbPyramids() == 1 +assert Mesh_1.NbPrisms() == 1 +assert Mesh_1.NbHexagonalPrisms() == 1 +assert Mesh_1.NbPolyhedrons() == 7 + + +if salome.sg.hasDesktop(): + salome.sg.updateObjBrowser() diff --git a/doc/salome/examples/tests.set b/doc/salome/examples/tests.set index 4f341f55e..f903c04b4 100644 --- a/doc/salome/examples/tests.set +++ b/doc/salome/examples/tests.set @@ -182,6 +182,7 @@ SET(GOOD_TESTS split_biquad.py quad_medial_axis_algo.py defining_hypotheses_len_near_vertex.py + test_polyhedron_per_solid.py ) SET(EXAMPLES_TESTS ${BAD_TESTS} ${GOOD_TESTS} testme.py) diff --git a/src/StdMeshers/StdMeshers_PolyhedronPerSolid_3D.cxx b/src/StdMeshers/StdMeshers_PolyhedronPerSolid_3D.cxx index eeb19d48e..5debedb31 100644 --- a/src/StdMeshers/StdMeshers_PolyhedronPerSolid_3D.cxx +++ b/src/StdMeshers/StdMeshers_PolyhedronPerSolid_3D.cxx @@ -196,6 +196,9 @@ namespace int iSide = trias[0] + 1; if ( iSide == trias[1] ) ++iSide; + if (iSide == 5) + // use first side (otherwise, out of bounds) + iSide = 0; const SMDS_MeshElement* botFace = faces[ trias[0]]; const SMDS_MeshElement* topFace = faces[ trias[1]]; From b586ea5065bb78c57dcaee29097c6fd8df52d1d0 Mon Sep 17 00:00:00 2001 From: eap Date: Thu, 28 Jan 2021 16:07:06 +0300 Subject: [PATCH 4/4] bos #20646 [CEA] Fix error in polyhedron per solid on pentahedron --- src/StdMeshers/StdMeshers_PolyhedronPerSolid_3D.cxx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/StdMeshers/StdMeshers_PolyhedronPerSolid_3D.cxx b/src/StdMeshers/StdMeshers_PolyhedronPerSolid_3D.cxx index 5debedb31..b8e108958 100644 --- a/src/StdMeshers/StdMeshers_PolyhedronPerSolid_3D.cxx +++ b/src/StdMeshers/StdMeshers_PolyhedronPerSolid_3D.cxx @@ -299,10 +299,6 @@ namespace if ( hexa[1] == -1 ) return newHexPrism; - int iSide = hexa[0] + 1; - if ( iSide == hexa[1] ) - ++iSide; - const SMDS_MeshElement* botFace = faces[ hexa[ 0 ]]; const SMDS_MeshElement* topFace = faces[ hexa[ 1 ]]; std::vector< const SMDS_MeshNode* > nodes( 24 ); // last 12 is a working buffer