1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2014-2024 EDF, OPEN CASCADE
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License, or (at your option) any later version.
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # Lesser General Public License for more details.
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 # Author : Alexey SOZINOV, Open CASCADE S.A.S.
23 ## @defgroup check_conformity CheckConformity - Wrapper to find imperfections in the shape
26 # This tool provides the user with a simple python API
27 # to analyze, available shape for Boolean Operations or not.
28 # Also tool provide advanced output to indicate imperfections in the input shape.
32 # from salome.geom import geomBuilder
33 # from salome.geom.CheckConformity import CheckConformity
35 # geompy = geomBuilder.New()
37 # O = geompy.MakeVertex(0, 0, 0)
38 # OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
39 # OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
40 # OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
41 # Vertex_1 = geompy.MakeVertex(-30, -70, 0)
42 # Vertex_2 = geompy.MakeVertex(-30, 50, 0)
43 # Line_1 = geompy.MakeLineTwoPnt(Vertex_2, Vertex_1)
44 # Vertex_3 = geompy.MakeVertex(0, -50, 0)
45 # Vertex_4 = geompy.MakeVertex(-40, -10, 0)
46 # Vertex_5 = geompy.MakeVertex(0, 40, 0)
47 # Arc_1 = geompy.MakeArc(Vertex_5, Vertex_4, Vertex_3)
48 # Vertex_6 = geompy.MakeVertex(10, -50, 4)
49 # Vertex_7 = geompy.MakeVertex(10, -50, 10)
50 # Vertex_8 = geompy.MakeVertex(10, 40, 10)
51 # Arc_1_vertex_3 = geompy.GetSubShape(Arc_1, [3])
52 # Line_2 = geompy.MakeLineTwoPnt(Arc_1_vertex_3, Vertex_6)
53 # Line_3 = geompy.MakeLineTwoPnt(Vertex_6, Vertex_7)
54 # Line_4 = geompy.MakeLineTwoPnt(Vertex_7, Vertex_8)
55 # Vertex_9 = geompy.MakeVertex(15, 40, 10)
56 # Vertex_10 = geompy.MakeVertex(17, 0, 6)
57 # Vertex_11 = geompy.MakeVertex(17, 0, 3)
58 # Line_5 = geompy.MakeLineTwoPnt(Vertex_8, Vertex_9)
59 # Line_6 = geompy.MakeLineTwoPnt(Vertex_9, Vertex_10)
60 # Line_7 = geompy.MakeLineTwoPnt(Vertex_10, Vertex_11)
61 # Arc_1_vertex_2 = geompy.GetSubShape(Arc_1, [2])
62 # Line_8 = geompy.MakeLineTwoPnt(Vertex_11, Arc_1_vertex_2)
63 # Wire_1 = geompy.MakeWire([Arc_1, Line_2, Line_3, Line_4, Line_5, Line_6, Line_7, Line_8], 1e-07)
64 # Wire_2 = geompy.MakeWire([Line_1], 1e-07)
65 # Compound_1 = geompy.MakeCompound([Wire_1, Wire_2])
67 # # Create class CheckConformity for check shape
68 # cc = CheckConformity(Compound_1, geompy)
69 # valid = cc.isValid()
70 # dist = cc.distantShapes()
71 # small = cc.smallEdges()
72 # interfer = cc.interferingSubshapes()
73 # intersect = cc.selfIntersected2D()
75 # geompy.addToStudy( O, 'O' )
76 # geompy.addToStudy( OX, 'OX' )
77 # geompy.addToStudy( OY, 'OY' )
78 # geompy.addToStudy( OZ, 'OZ' )
79 # geompy.addToStudy( Vertex_1, 'Vertex_1' )
80 # geompy.addToStudy( Vertex_2, 'Vertex_2' )
81 # geompy.addToStudy( Line_1, 'Line_1' )
82 # geompy.addToStudy( Vertex_3, 'Vertex_3' )
83 # geompy.addToStudy( Vertex_4, 'Vertex_4' )
84 # geompy.addToStudy( Vertex_5, 'Vertex_5' )
85 # geompy.addToStudy( Arc_1, 'Arc_1' )
86 # geompy.addToStudy( Vertex_6, 'Vertex_6' )
87 # geompy.addToStudy( Vertex_7, 'Vertex_7' )
88 # geompy.addToStudy( Vertex_8, 'Vertex_8' )
89 # geompy.addToStudyInFather( Arc_1, Arc_1_vertex_3, 'Arc_1:vertex_3' )
90 # geompy.addToStudy( Line_2, 'Line_2' )
91 # geompy.addToStudy( Line_3, 'Line_3' )
92 # geompy.addToStudy( Line_4, 'Line_4' )
93 # geompy.addToStudy( Vertex_9, 'Vertex_9' )
94 # geompy.addToStudy( Vertex_10, 'Vertex_10' )
95 # geompy.addToStudy( Vertex_11, 'Vertex_11' )
96 # geompy.addToStudy( Line_5, 'Line_5' )
97 # geompy.addToStudy( Line_6, 'Line_6' )
98 # geompy.addToStudy( Line_7, 'Line_7' )
99 # geompy.addToStudyInFather( Arc_1, Arc_1_vertex_2, 'Arc_1:vertex_2' )
100 # geompy.addToStudy( Line_8, 'Line_8' )
101 # geompy.addToStudy( Wire_1, 'Wire_1' )
102 # geompy.addToStudy( Wire_2, 'Wire_2' )
103 # geompy.addToStudy( Compound_1, 'Compound_1' )
105 # salome.sg.updateObjBrowser()
108 # @n Additional examples can be found as unit tests in the source code.
112 ## An interface to find imperfections in the shape.
113 # Use geompy.CheckConformity(shape) method to obtain an instance of this class
115 # @ref tui_check_conformity_page "Example"
116 # @ingroup check_conformity
117 class CheckConformity:
121 Check Conformity interface
124 cc = CheckConformity(Lot4_twistedFace_brep_1, geompy)
126 dist = cc.distantShapes(geompy.ShapeType["EDGE"], geompy.ShapeType["VERTEX"])
127 small = cc.smallEdges()
128 interfer = cc.interferingSubshapes()
129 interferEV = cc.interferingSubshapes(geompy.ShapeType["EDGE"], geompy.ShapeType["VERTEX"])
130 interferVV = cc.interferingSubshapes(geompy.ShapeType["VERTEX], geompy.ShapeType["VERTEX"])
131 intersect = cc.selfIntersected2D()
134 def __init__(self, shape, geompyD):
135 self.geompyD = geompyD
137 self.myIsChecked = False;
140 ## Perform analyse of shape.
142 # @return New List, which contains pair: type of check and single of pair failed sub-shapes.
143 def __checkShape(self):
145 Perform analyse of shape.
148 New List, which contains pair: type of check and single of pair failed sub-shapes.
150 anOp = self.geompyD.GetIMeasureOperations()
151 self.myResults = anOp.CheckConformityShape(self.myShape)
152 self.myIsChecked = True
154 ## Check whether the shape is applicable for Boolean Operations.
156 # @return Boolean value True if shape is applicable for Boolean Operations, otherwise - False
159 check whether the shape is applicable for Boolean Operations.
162 Boolean value True if shape is applicable for Boolean Operations, otherwise - False.
165 Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
166 cc = CheckConformity(Box_1, geompy)
167 isValid = cc.isValid()
169 if not self.myIsChecked:
171 return len(self.myResults) == 0
173 ## Find all self-intersected 2D curves.
175 # @return New List, of pair sub-shape, which has self-intersected in 2D
176 def selfIntersected2D(self):
178 Find all self-intersected 2D curves.
181 New List, of pair sub-shape, which has self-intersected in 2D/
184 Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
185 cc = CheckConformity(Box_1, geompy)
186 selfIntersected2D = cc.selfIntersected2D()
188 if not self.myIsChecked:
191 anOp = self.geompyD.GetIMeasureOperations()
192 return anOp.SelfIntersected2D(self.myResults)
194 ## Find pairs of interfering sub-shapes:
195 # - vertices touched by tolerance;
196 # - vertex touching an edge in the inner point;
197 # - vertex lying on the inner point of a face;
198 # - edges intersecting by inner points;
199 # - edge touching/intersecting face in the inner point;
200 # - faces intersection by inner point
202 # Types of interfering shapes could be specified,
203 # by default all pairs of interfering shapes are returned.
205 # @param shapeType1 first type of shape
206 # @param shapeType2 second type of shape
208 # @return New List, of pairs of interfering shapes with given types (if they was specified)
209 def interferingSubshapes(self, shapeType1 = AUTO, shapeType2 = AUTO):
211 Find pairs of interfering sub-shapes:
212 - vertices touched by tolerance
213 - vertex touching an edge in the inner point
214 - vertex lying on the inner point of a face
215 - edges intersecting by inner points
216 - edge touching/intersecting face in the inner point
217 - faces intersection by inner point
219 Types of interfering shapes could be specified, by default all pairs of
220 interfering shapes are returned.
223 shapeType1 first type of shape
224 shapeType2 second type of shape
227 New List, of pairs of interfering shapes with given types (if they was specified)
230 Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
231 cc = CheckConformity(Box_1, geompy)
232 interferingSubshapes = cc.interferingSubshapes()
233 interferingSubshapesVV = cc.interferingSubshapes(geompy.ShapeType["VERTEX"], geompy.ShapeType["VERTEX"])
235 if not self.myIsChecked:
238 anOp = self.geompyD.GetIMeasureOperations()
239 return anOp.InterferingSubshapes(self.myResults, shapeType1, shapeType2)
241 ## Find edges, which are fully covered by tolerances of vertices.
243 # @return New List of edges, which are fully covered by tolerances of vertices
244 def smallEdges(self):
246 Find edges, which are fully covered by tolerances of vertices.
249 New List of edges, which are fully covered by tolerances of vertices.
252 Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
253 cc = CheckConformity(Box_1, geompy)
254 smallEdges = cc.smallEdges()
256 if not self.myIsChecked:
259 anOp = self.geompyD.GetIMeasureOperations()
260 return anOp.SmallEdges(self.myResults)
262 ## Find remote objects (sub-shape on a shape):
263 # - vertex far from edge;
264 # - vertex far from face;
265 # - edge far from face
267 # Sub-shape which are lying far from its parent shape more than the given tolerance.
269 # @param shapeType type of shape
270 # @param subShapeType type of sub-shape
271 # @param tolerance available tolerance, by default used tolerance of sub-shape.
273 # @return New List, of pair of sub-shape with given types,
274 # that lying far from its parent shape more than the given tolerance.
275 def distantShapes(self, shapeType = AUTO, subShapeType = AUTO, tolerance = -1.0):
277 Find remote objects (sub-shape on a shape):
278 - vertex far from edge;
279 - vertex far from face;
282 Sub-shape which are lying far from its parent shape more than the given tolerance.
285 shapeType type of shape
286 subShapeType type of sub-shape
287 tolerance available tolerance, by default used tolerance of sub-shape.
290 New List, of pair of sub-shape with given types,
291 that lying far from its parent shape more than the given tolerance
294 Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
295 cc = CheckConformity(Box_1, geompy)
296 distantShapes = cc.distantShapes(geompy.ShapeType["EDGE"], geompy.ShapeType["VERTEX"])
298 if not self.myIsChecked:
301 anOp = self.geompyD.GetIMeasureOperations()
302 return anOp.DistantShapes(self.myResults, shapeType, subShapeType, tolerance)
304 ## Compute possible tolerance for the shape,
305 # minimize tolerance of shape as well as tolerance of sub-shapes as much as possible .
307 # @return New value of tolerance.
308 def updateTolerance(self):
310 Compute possible tolerance for the shape,
311 minimize tolerance of shape as well as tolerance of sub-shapes as much as possible.
314 New value of tolerance.
317 Box_1 = geompy.MakeBoxDXDYDZ(200, 200, 200)
318 cc = CheckConformity(Box_1, geompy)
319 toler = cc.updateTolerance()
321 anOp = self.geompyD.GetIMeasureOperations()
322 return anOp.UpdateTolerance(self.myShape)