1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include <Standard_Stream.hxx>
25 #include <GEOMImpl_IMeasureOperations.hxx>
27 #include <GEOMImpl_Types.hxx>
28 #include <GEOMImpl_MeasureDriver.hxx>
29 #include <GEOMImpl_IMeasure.hxx>
30 #include <GEOMImpl_IShapesOperations.hxx>
32 #include <GEOMUtils.hxx>
34 #include <GEOMAlgo_ShapeInfo.hxx>
35 #include <GEOMAlgo_ShapeInfoFiller.hxx>
37 #include <GEOM_Function.hxx>
38 #include <GEOM_PythonDump.hxx>
40 #include <Basics_OCCTVersion.hxx>
42 #include <utilities.h>
44 #include <Utils_ExceptHandlers.hxx>
47 #include <TFunction_DriverTable.hxx>
48 #include <TFunction_Driver.hxx>
49 #include <TFunction_Logbook.hxx>
50 #include <TDF_Tool.hxx>
52 #include <BRep_Builder.hxx>
53 #include <BRep_TFace.hxx>
54 #include <BRep_Tool.hxx>
55 #include <BRepAdaptor_Surface.hxx>
56 #include <BRepBuilderAPI_Copy.hxx>
57 #include <BRepBndLib.hxx>
58 #include <BRepCheck.hxx>
59 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
60 #include <BRepCheck_Result.hxx>
61 #include <BRepCheck_Shell.hxx>
62 #include <BRepClass3d_SolidClassifier.hxx>
63 #include <BRepExtrema_DistShapeShape.hxx>
64 #include <BRepGProp.hxx>
65 #include <BRepTools.hxx>
67 #include <Bnd_Box.hxx>
72 #include <TopoDS_Edge.hxx>
73 #include <TopoDS_Face.hxx>
74 #include <TopoDS_Shape.hxx>
75 #include <TopoDS_Vertex.hxx>
76 #include <TopoDS_Compound.hxx>
77 #include <TopoDS_Iterator.hxx>
78 #include <TopExp_Explorer.hxx>
79 #include <TopTools_MapOfShape.hxx>
80 #include <TopTools_ListOfShape.hxx>
81 #include <TopTools_ListIteratorOfListOfShape.hxx>
83 #include <ShapeAnalysis.hxx>
84 #include <ShapeAnalysis_Surface.hxx>
86 #include <GeomAPI_IntSS.hxx>
87 #include <GeomAPI_ProjectPointOnCurve.hxx>
89 #include <GeomAbs_SurfaceType.hxx>
91 #include <Geom_Line.hxx>
92 #include <Geom_Surface.hxx>
94 #include <GeomLProp_CLProps.hxx>
95 #include <GeomLProp_SLProps.hxx>
97 #include <GProp_GProps.hxx>
98 #include <GProp_PrincipalProps.hxx>
100 #include <gp_Pln.hxx>
101 #include <gp_Lin.hxx>
103 #include <BOPCol_ListOfShape.hxx>
104 #include <BOPDS_DS.hxx>
105 #include <BOPDS_MapOfPassKey.hxx>
106 #include <BOPDS_PassKey.hxx>
107 #include <GEOMAlgo_AlgoTools.hxx>
108 #include <BOPAlgo_CheckerSI.hxx>
110 #include <Standard_Failure.hxx>
111 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
113 //=============================================================================
117 //=============================================================================
118 GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations (GEOM_Engine* theEngine, int theDocID)
119 : GEOM_IOperations(theEngine, theDocID)
121 MESSAGE("GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations");
124 //=============================================================================
128 //=============================================================================
129 GEOMImpl_IMeasureOperations::~GEOMImpl_IMeasureOperations()
131 MESSAGE("GEOMImpl_IMeasureOperations::~GEOMImpl_IMeasureOperations");
134 //=============================================================================
135 /*! Get kind and parameters of the given shape.
137 //=============================================================================
138 GEOMImpl_IMeasureOperations::ShapeKind GEOMImpl_IMeasureOperations::KindOfShape
139 (Handle(GEOM_Object) theShape,
140 Handle(TColStd_HSequenceOfInteger)& theIntegers,
141 Handle(TColStd_HSequenceOfReal)& theDoubles)
144 ShapeKind aKind = SK_NO_SHAPE;
146 if (theIntegers.IsNull()) theIntegers = new TColStd_HSequenceOfInteger;
147 else theIntegers->Clear();
149 if (theDoubles.IsNull()) theDoubles = new TColStd_HSequenceOfReal;
150 else theDoubles->Clear();
152 if (theShape.IsNull())
155 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
156 if (aRefShape.IsNull()) return aKind;
158 TopoDS_Shape aShape = aRefShape->GetValue();
159 if (aShape.IsNull()) return aKind;
161 int geom_type = theShape->GetType();
163 // check if it's advanced shape
164 if ( geom_type > ADVANCED_BASE ) {
170 GEOMAlgo_ShapeInfoFiller aSF;
171 aSF.SetShape(aShape);
173 Standard_Integer iErr = aSF.ErrorStatus();
175 SetErrorCode("Error in GEOMAlgo_ShapeInfoFiller");
178 const GEOMAlgo_ShapeInfo& anInfo = aSF.Info();
180 // Interprete results
181 TopAbs_ShapeEnum aType = anInfo.Type();
184 case TopAbs_COMPOUND:
185 case TopAbs_COMPSOLID:
187 // (+) geompy.kind.COMPOUND nb_solids nb_faces nb_edges nb_vertices
188 // (+) geompy.kind.COMPSOLID nb_solids nb_faces nb_edges nb_vertices
189 // ??? "nb_faces" - all faces or only 'standalone' faces?
190 if (aType == TopAbs_COMPOUND)
193 aKind = SK_COMPSOLID;
195 //theIntegers->Append(anInfo.NbSubShapes(TopAbs_COMPOUND));
196 //theIntegers->Append(anInfo.NbSubShapes(TopAbs_COMPSOLID));
197 theIntegers->Append(anInfo.NbSubShapes(TopAbs_SOLID));
198 theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
199 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
200 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
206 // (+) geompy.kind.SHELL geompy.info.closed nb_faces nb_edges nb_vertices
207 // (+) geompy.kind.SHELL geompy.info.unclosed nb_faces nb_edges nb_vertices
210 theIntegers->Append((int)anInfo.KindOfClosed());
212 theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
213 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
214 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
220 // (+) geompy.kind.WIRE geompy.info.closed nb_edges nb_vertices
221 // (+) geompy.kind.WIRE geompy.info.unclosed nb_edges nb_vertices
224 theIntegers->Append((int)anInfo.KindOfClosed());
226 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
227 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
235 GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
238 case GEOMAlgo_KN_SPHERE:
239 // (+) geompy.kind.SPHERE xc yc zc R
243 gp_Pnt aC = anInfo.Location();
244 theDoubles->Append(aC.X());
245 theDoubles->Append(aC.Y());
246 theDoubles->Append(aC.Z());
248 theDoubles->Append(anInfo.Radius1());
251 case GEOMAlgo_KN_CYLINDER:
252 // (+) geompy.kind.CYLINDER xb yb zb dx dy dz R H
256 gp_Pnt aC = anInfo.Location();
257 theDoubles->Append(aC.X());
258 theDoubles->Append(aC.Y());
259 theDoubles->Append(aC.Z());
261 gp_Ax3 anAx3 = anInfo.Position();
262 gp_Dir aD = anAx3.Direction();
263 theDoubles->Append(aD.X());
264 theDoubles->Append(aD.Y());
265 theDoubles->Append(aD.Z());
267 theDoubles->Append(anInfo.Radius1());
268 theDoubles->Append(anInfo.Height());
271 case GEOMAlgo_KN_BOX:
272 // (+) geompy.kind.BOX xc yc zc ax ay az
276 gp_Pnt aC = anInfo.Location();
277 theDoubles->Append(aC.X());
278 theDoubles->Append(aC.Y());
279 theDoubles->Append(aC.Z());
281 gp_Ax3 anAx3 = anInfo.Position();
282 gp_Dir aD = anAx3.Direction();
283 gp_Dir aX = anAx3.XDirection();
286 if (aD.IsParallel(gp::DZ(), Precision::Angular()) &&
287 aX.IsParallel(gp::DX(), Precision::Angular())) {
288 theDoubles->Append(anInfo.Length()); // ax'
289 theDoubles->Append(anInfo.Width()); // ay'
290 theDoubles->Append(anInfo.Height()); // az'
292 else if (aD.IsParallel(gp::DZ(), Precision::Angular()) &&
293 aX.IsParallel(gp::DY(), Precision::Angular())) {
294 theDoubles->Append(anInfo.Width()); // ay'
295 theDoubles->Append(anInfo.Length()); // ax'
296 theDoubles->Append(anInfo.Height()); // az'
298 else if (aD.IsParallel(gp::DX(), Precision::Angular()) &&
299 aX.IsParallel(gp::DZ(), Precision::Angular())) {
300 theDoubles->Append(anInfo.Height()); // az'
301 theDoubles->Append(anInfo.Width()); // ay'
302 theDoubles->Append(anInfo.Length()); // ax'
304 else if (aD.IsParallel(gp::DX(), Precision::Angular()) &&
305 aX.IsParallel(gp::DY(), Precision::Angular())) {
306 theDoubles->Append(anInfo.Height()); // az'
307 theDoubles->Append(anInfo.Length()); // ax'
308 theDoubles->Append(anInfo.Width()); // ay'
310 else if (aD.IsParallel(gp::DY(), Precision::Angular()) &&
311 aX.IsParallel(gp::DZ(), Precision::Angular())) {
312 theDoubles->Append(anInfo.Width()); // ay'
313 theDoubles->Append(anInfo.Height()); // az'
314 theDoubles->Append(anInfo.Length()); // ax'
316 else if (aD.IsParallel(gp::DY(), Precision::Angular()) &&
317 aX.IsParallel(gp::DX(), Precision::Angular())) {
318 theDoubles->Append(anInfo.Length()); // ax'
319 theDoubles->Append(anInfo.Height()); // az'
320 theDoubles->Append(anInfo.Width()); // ay'
323 // (+) geompy.kind.ROTATED_BOX xo yo zo zx zy zz xx xy xz ax ay az
324 aKind = SK_ROTATED_BOX;
326 // Direction and XDirection
327 theDoubles->Append(aD.X());
328 theDoubles->Append(aD.Y());
329 theDoubles->Append(aD.Z());
331 theDoubles->Append(aX.X());
332 theDoubles->Append(aX.Y());
333 theDoubles->Append(aX.Z());
336 theDoubles->Append(anInfo.Length());
337 theDoubles->Append(anInfo.Width());
338 theDoubles->Append(anInfo.Height());
342 case GEOMAlgo_KN_TORUS:
343 // (+) geompy.kind.TORUS xc yc zc dx dy dz R_1 R_2
347 gp_Pnt aO = anInfo.Location();
348 theDoubles->Append(aO.X());
349 theDoubles->Append(aO.Y());
350 theDoubles->Append(aO.Z());
352 gp_Ax3 anAx3 = anInfo.Position();
353 gp_Dir aD = anAx3.Direction();
354 theDoubles->Append(aD.X());
355 theDoubles->Append(aD.Y());
356 theDoubles->Append(aD.Z());
358 theDoubles->Append(anInfo.Radius1());
359 theDoubles->Append(anInfo.Radius2());
362 case GEOMAlgo_KN_CONE:
363 // (+) geompy.kind.CONE xb yb zb dx dy dz R_1 R_2 H
367 gp_Pnt aO = anInfo.Location();
368 theDoubles->Append(aO.X());
369 theDoubles->Append(aO.Y());
370 theDoubles->Append(aO.Z());
372 gp_Ax3 anAx3 = anInfo.Position();
373 gp_Dir aD = anAx3.Direction();
374 theDoubles->Append(aD.X());
375 theDoubles->Append(aD.Y());
376 theDoubles->Append(aD.Z());
378 theDoubles->Append(anInfo.Radius1());
379 theDoubles->Append(anInfo.Radius2());
380 theDoubles->Append(anInfo.Height());
383 case GEOMAlgo_KN_POLYHEDRON:
384 // (+) geompy.kind.POLYHEDRON nb_faces nb_edges nb_vertices
386 aKind = SK_POLYHEDRON;
388 theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
389 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
390 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
394 // (+) geompy.kind.SOLID nb_faces nb_edges nb_vertices
396 theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
397 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
398 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
408 GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
410 case GEOMAlgo_KN_SPHERE:
411 // (+) geompy.kind.SPHERE2D xc yc zc R
415 gp_Pnt aC = anInfo.Location();
416 theDoubles->Append(aC.X());
417 theDoubles->Append(aC.Y());
418 theDoubles->Append(aC.Z());
420 theDoubles->Append(anInfo.Radius1());
423 case GEOMAlgo_KN_CYLINDER:
424 // (+) geompy.kind.CYLINDER2D xb yb zb dx dy dz R H
426 aKind = SK_CYLINDER2D;
428 gp_Pnt aO = anInfo.Location();
429 theDoubles->Append(aO.X());
430 theDoubles->Append(aO.Y());
431 theDoubles->Append(aO.Z());
433 gp_Ax3 anAx3 = anInfo.Position();
434 gp_Dir aD = anAx3.Direction();
435 theDoubles->Append(aD.X());
436 theDoubles->Append(aD.Y());
437 theDoubles->Append(aD.Z());
439 theDoubles->Append(anInfo.Radius1());
440 theDoubles->Append(anInfo.Height());
443 case GEOMAlgo_KN_TORUS:
444 // (+) geompy.kind.TORUS2D xc yc zc dx dy dz R_1 R_2
448 gp_Pnt aO = anInfo.Location();
449 theDoubles->Append(aO.X());
450 theDoubles->Append(aO.Y());
451 theDoubles->Append(aO.Z());
453 gp_Ax3 anAx3 = anInfo.Position();
454 gp_Dir aD = anAx3.Direction();
455 theDoubles->Append(aD.X());
456 theDoubles->Append(aD.Y());
457 theDoubles->Append(aD.Z());
459 theDoubles->Append(anInfo.Radius1());
460 theDoubles->Append(anInfo.Radius2());
463 case GEOMAlgo_KN_CONE:
464 // (+) geompy.kind.CONE2D xc yc zc dx dy dz R_1 R_2 H
468 gp_Pnt aO = anInfo.Location();
469 theDoubles->Append(aO.X());
470 theDoubles->Append(aO.Y());
471 theDoubles->Append(aO.Z());
473 gp_Ax3 anAx3 = anInfo.Position();
474 gp_Dir aD = anAx3.Direction();
475 theDoubles->Append(aD.X());
476 theDoubles->Append(aD.Y());
477 theDoubles->Append(aD.Z());
479 theDoubles->Append(anInfo.Radius1());
480 theDoubles->Append(anInfo.Radius2());
481 theDoubles->Append(anInfo.Height());
484 case GEOMAlgo_KN_DISKCIRCLE:
485 // (+) geompy.kind.DISK_CIRCLE xc yc zc dx dy dz R
487 aKind = SK_DISK_CIRCLE;
489 gp_Pnt aC = anInfo.Location();
490 theDoubles->Append(aC.X());
491 theDoubles->Append(aC.Y());
492 theDoubles->Append(aC.Z());
494 gp_Ax3 anAx3 = anInfo.Position();
495 gp_Dir aD = anAx3.Direction();
496 theDoubles->Append(aD.X());
497 theDoubles->Append(aD.Y());
498 theDoubles->Append(aD.Z());
500 theDoubles->Append(anInfo.Radius1());
503 case GEOMAlgo_KN_DISKELLIPSE:
504 // (+) geompy.kind.DISK_ELLIPSE xc yc zc dx dy dz R_1 R_2
506 aKind = SK_DISK_ELLIPSE;
508 gp_Pnt aC = anInfo.Location();
509 theDoubles->Append(aC.X());
510 theDoubles->Append(aC.Y());
511 theDoubles->Append(aC.Z());
513 gp_Ax3 anAx3 = anInfo.Position();
514 gp_Dir aD = anAx3.Direction();
515 theDoubles->Append(aD.X());
516 theDoubles->Append(aD.Y());
517 theDoubles->Append(aD.Z());
519 theDoubles->Append(anInfo.Radius1());
520 theDoubles->Append(anInfo.Radius2());
523 case GEOMAlgo_KN_RECTANGLE:
524 case GEOMAlgo_KN_TRIANGLE:
525 case GEOMAlgo_KN_QUADRANGLE:
526 case GEOMAlgo_KN_POLYGON:
527 // (+) geompy.kind.POLYGON xo yo zo dx dy dz nb_edges nb_vertices
531 gp_Pnt aO = anInfo.Location();
532 theDoubles->Append(aO.X());
533 theDoubles->Append(aO.Y());
534 theDoubles->Append(aO.Z());
536 gp_Ax3 anAx3 = anInfo.Position();
537 gp_Dir aD = anAx3.Direction();
538 theDoubles->Append(aD.X());
539 theDoubles->Append(aD.Y());
540 theDoubles->Append(aD.Z());
542 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
543 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
546 case GEOMAlgo_KN_PLANE: // infinite
547 // (+) geompy.kind.PLANE xo yo zo dx dy dz
551 gp_Pnt aC = anInfo.Location();
552 theDoubles->Append(aC.X());
553 theDoubles->Append(aC.Y());
554 theDoubles->Append(aC.Z());
556 gp_Ax3 anAx3 = anInfo.Position();
557 gp_Dir aD = anAx3.Direction();
558 theDoubles->Append(aD.X());
559 theDoubles->Append(aD.Y());
560 theDoubles->Append(aD.Z());
564 if (anInfo.KindOfShape() == GEOMAlgo_KS_PLANE) {
565 // (+) geompy.kind.PLANAR xo yo zo dx dy dz nb_edges nb_vertices
569 gp_Pnt aC = anInfo.Location();
570 theDoubles->Append(aC.X());
571 theDoubles->Append(aC.Y());
572 theDoubles->Append(aC.Z());
574 gp_Ax3 anAx3 = anInfo.Position();
575 gp_Dir aD = anAx3.Direction();
576 theDoubles->Append(aD.X());
577 theDoubles->Append(aD.Y());
578 theDoubles->Append(aD.Z());
580 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
581 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
584 // ??? geompy.kind.FACE nb_edges nb_vertices _surface_type_id_
585 // (+) geompy.kind.FACE nb_edges nb_vertices
587 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
588 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
598 GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
600 case GEOMAlgo_KN_CIRCLE:
602 // (+) geompy.kind.CIRCLE xc yc zc dx dy dz R
605 gp_Pnt aC = anInfo.Location();
606 theDoubles->Append(aC.X());
607 theDoubles->Append(aC.Y());
608 theDoubles->Append(aC.Z());
610 gp_Ax3 anAx3 = anInfo.Position();
611 gp_Dir aD = anAx3.Direction();
612 theDoubles->Append(aD.X());
613 theDoubles->Append(aD.Y());
614 theDoubles->Append(aD.Z());
616 theDoubles->Append(anInfo.Radius1());
619 case GEOMAlgo_KN_ARCCIRCLE:
621 // (+) geompy.kind.ARC_CIRCLE xc yc zc dx dy dz R x1 y1 z1 x2 y2 z2
622 aKind = SK_ARC_CIRCLE;
624 gp_Pnt aC = anInfo.Location();
625 theDoubles->Append(aC.X());
626 theDoubles->Append(aC.Y());
627 theDoubles->Append(aC.Z());
629 gp_Ax3 anAx3 = anInfo.Position();
630 gp_Dir aD = anAx3.Direction();
631 theDoubles->Append(aD.X());
632 theDoubles->Append(aD.Y());
633 theDoubles->Append(aD.Z());
635 theDoubles->Append(anInfo.Radius1());
637 gp_Pnt aP1 = anInfo.Pnt1();
638 theDoubles->Append(aP1.X());
639 theDoubles->Append(aP1.Y());
640 theDoubles->Append(aP1.Z());
642 gp_Pnt aP2 = anInfo.Pnt2();
643 theDoubles->Append(aP2.X());
644 theDoubles->Append(aP2.Y());
645 theDoubles->Append(aP2.Z());
648 case GEOMAlgo_KN_ELLIPSE:
650 // (+) geompy.kind.ELLIPSE xc yc zc dx dy dz R_1 R_2
653 gp_Pnt aC = anInfo.Location();
654 theDoubles->Append(aC.X());
655 theDoubles->Append(aC.Y());
656 theDoubles->Append(aC.Z());
658 gp_Ax3 anAx3 = anInfo.Position();
659 gp_Dir aD = anAx3.Direction();
660 theDoubles->Append(aD.X());
661 theDoubles->Append(aD.Y());
662 theDoubles->Append(aD.Z());
664 theDoubles->Append(anInfo.Radius1());
665 theDoubles->Append(anInfo.Radius2());
668 case GEOMAlgo_KN_ARCELLIPSE:
670 // (+) geompy.kind.ARC_ELLIPSE xc yc zc dx dy dz R_1 R_2 x1 y1 z1 x2 y2 z2
671 aKind = SK_ARC_ELLIPSE;
673 gp_Pnt aC = anInfo.Location();
674 theDoubles->Append(aC.X());
675 theDoubles->Append(aC.Y());
676 theDoubles->Append(aC.Z());
678 gp_Ax3 anAx3 = anInfo.Position();
679 gp_Dir aD = anAx3.Direction();
680 theDoubles->Append(aD.X());
681 theDoubles->Append(aD.Y());
682 theDoubles->Append(aD.Z());
684 theDoubles->Append(anInfo.Radius1());
685 theDoubles->Append(anInfo.Radius2());
687 gp_Pnt aP1 = anInfo.Pnt1();
688 theDoubles->Append(aP1.X());
689 theDoubles->Append(aP1.Y());
690 theDoubles->Append(aP1.Z());
692 gp_Pnt aP2 = anInfo.Pnt2();
693 theDoubles->Append(aP2.X());
694 theDoubles->Append(aP2.Y());
695 theDoubles->Append(aP2.Z());
698 case GEOMAlgo_KN_LINE:
700 // ??? geompy.kind.LINE x1 y1 z1 x2 y2 z2
701 // (+) geompy.kind.LINE x1 y1 z1 dx dy dz
704 gp_Pnt aO = anInfo.Location();
705 theDoubles->Append(aO.X());
706 theDoubles->Append(aO.Y());
707 theDoubles->Append(aO.Z());
709 gp_Dir aD = anInfo.Direction();
710 theDoubles->Append(aD.X());
711 theDoubles->Append(aD.Y());
712 theDoubles->Append(aD.Z());
715 case GEOMAlgo_KN_SEGMENT:
717 // (+) geompy.kind.SEGMENT x1 y1 z1 x2 y2 z2
720 gp_Pnt aP1 = anInfo.Pnt1();
721 theDoubles->Append(aP1.X());
722 theDoubles->Append(aP1.Y());
723 theDoubles->Append(aP1.Z());
725 gp_Pnt aP2 = anInfo.Pnt2();
726 theDoubles->Append(aP2.X());
727 theDoubles->Append(aP2.Y());
728 theDoubles->Append(aP2.Z());
732 // ??? geompy.kind.EDGE nb_vertices _curve_type_id_
733 // (+) geompy.kind.EDGE nb_vertices
734 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
741 // (+) geompy.kind.VERTEX x y z
744 gp_Pnt aP = anInfo.Location();
745 theDoubles->Append(aP.X());
746 theDoubles->Append(aP.Y());
747 theDoubles->Append(aP.Z());
756 //=============================================================================
760 //=============================================================================
761 void GEOMImpl_IMeasureOperations::GetPosition
762 (Handle(GEOM_Object) theShape,
763 Standard_Real& Ox, Standard_Real& Oy, Standard_Real& Oz,
764 Standard_Real& Zx, Standard_Real& Zy, Standard_Real& Zz,
765 Standard_Real& Xx, Standard_Real& Xy, Standard_Real& Xz)
769 //Set default values: global CS
770 Ox = Oy = Oz = Zx = Zy = Xy = Xz = 0.;
773 if (theShape.IsNull()) return;
775 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
776 if (aRefShape.IsNull()) return;
778 TopoDS_Shape aShape = aRefShape->GetValue();
779 if (aShape.IsNull()) {
780 SetErrorCode("The Objects has NULL Shape");
785 #if OCC_VERSION_LARGE > 0x06010000
789 gp_Ax3 anAx3 = GEOMUtils::GetPosition(aShape);
791 gp_Pnt anOri = anAx3.Location();
792 gp_Dir aDirZ = anAx3.Direction();
793 gp_Dir aDirX = anAx3.XDirection();
796 anOri.Coord(Ox, Oy, Oz);
797 aDirZ.Coord(Zx, Zy, Zz);
798 aDirX.Coord(Xx, Xy, Xz);
800 catch (Standard_Failure) {
801 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
802 SetErrorCode(aFail->GetMessageString());
809 //=============================================================================
813 //=============================================================================
814 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetCentreOfMass
815 (Handle(GEOM_Object) theShape)
819 if (theShape.IsNull()) return NULL;
821 //Add a new CentreOfMass object
822 Handle(GEOM_Object) aCDG = GetEngine()->AddObject(GetDocID(), GEOM_CDG);
824 //Add a new CentreOfMass function
825 Handle(GEOM_Function) aFunction =
826 aCDG->AddFunction(GEOMImpl_MeasureDriver::GetID(), CDG_MEASURE);
827 if (aFunction.IsNull()) return NULL;
829 //Check if the function is set correctly
830 if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
832 GEOMImpl_IMeasure aCI (aFunction);
834 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
835 if (aRefShape.IsNull()) return NULL;
837 aCI.SetBase(aRefShape);
839 //Compute the CentreOfMass value
841 #if OCC_VERSION_LARGE > 0x06010000
844 if (!GetSolver()->ComputeFunction(aFunction)) {
845 SetErrorCode("Measure driver failed to compute centre of mass");
849 catch (Standard_Failure) {
850 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
851 SetErrorCode(aFail->GetMessageString());
855 //Make a Python command
856 GEOM::TPythonDump(aFunction) << aCDG << " = geompy.MakeCDG(" << theShape << ")";
862 //=============================================================================
866 //=============================================================================
867 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetVertexByIndex
868 (Handle(GEOM_Object) theShape,
869 Standard_Integer theIndex)
873 if (theShape.IsNull()) return NULL;
875 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
876 if (aRefShape.IsNull()) return NULL;
878 //Add a new Vertex object
879 Handle(GEOM_Object) aVertex = GetEngine()->AddObject(GetDocID(), GEOM_POINT);
882 Handle(GEOM_Function) aFunction =
883 aVertex->AddFunction(GEOMImpl_MeasureDriver::GetID(), VERTEX_BY_INDEX);
884 if (aFunction.IsNull()) return NULL;
886 //Check if the function is set correctly
887 if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
889 GEOMImpl_IMeasure aCI (aFunction);
890 aCI.SetBase(aRefShape);
891 aCI.SetIndex(theIndex);
895 #if OCC_VERSION_LARGE > 0x06010000
898 if (!GetSolver()->ComputeFunction(aFunction)) {
899 SetErrorCode("Vertex by index driver failed.");
903 catch (Standard_Failure) {
904 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
905 SetErrorCode(aFail->GetMessageString());
909 //Make a Python command
910 GEOM::TPythonDump(aFunction) << aVertex << " = geompy.GetVertexByIndex(" << theShape << ", " << theIndex << ")";
916 //=============================================================================
920 //=============================================================================
921 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetNormal
922 (Handle(GEOM_Object) theFace,
923 Handle(GEOM_Object) theOptionalPoint)
927 if (theFace.IsNull()) return NULL;
929 //Add a new Normale object
930 Handle(GEOM_Object) aNorm = GetEngine()->AddObject(GetDocID(), GEOM_VECTOR);
932 //Add a new Normale function
933 Handle(GEOM_Function) aFunction =
934 aNorm->AddFunction(GEOMImpl_MeasureDriver::GetID(), VECTOR_FACE_NORMALE);
935 if (aFunction.IsNull()) return NULL;
937 //Check if the function is set correctly
938 if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
940 GEOMImpl_IMeasure aCI (aFunction);
942 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
943 if (aFace.IsNull()) return NULL;
947 if (!theOptionalPoint.IsNull()) {
948 Handle(GEOM_Function) anOptPnt = theOptionalPoint->GetLastFunction();
949 aCI.SetPoint(anOptPnt);
952 //Compute the Normale value
954 #if OCC_VERSION_LARGE > 0x06010000
957 if (!GetSolver()->ComputeFunction(aFunction)) {
958 SetErrorCode("Measure driver failed to compute normake of face");
962 catch (Standard_Failure) {
963 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
964 SetErrorCode(aFail->GetMessageString());
968 //Make a Python command
969 GEOM::TPythonDump pd (aFunction);
970 pd << aNorm << " = geompy.GetNormal(" << theFace;
971 if (!theOptionalPoint.IsNull()) {
972 pd << ", " << theOptionalPoint;
980 //=============================================================================
984 //=============================================================================
985 void GEOMImpl_IMeasureOperations::GetBasicProperties (Handle(GEOM_Object) theShape,
986 Standard_Real& theLength,
987 Standard_Real& theSurfArea,
988 Standard_Real& theVolume)
992 if (theShape.IsNull()) return;
994 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
995 if (aRefShape.IsNull()) return;
997 TopoDS_Shape aShape = aRefShape->GetValue();
998 if (aShape.IsNull()) {
999 SetErrorCode("The Objects has NULL Shape");
1003 //Compute the parameters
1004 GProp_GProps LProps, SProps;
1006 #if OCC_VERSION_LARGE > 0x06010000
1009 BRepGProp::LinearProperties(aShape, LProps);
1010 theLength = LProps.Mass();
1012 BRepGProp::SurfaceProperties(aShape, SProps);
1013 theSurfArea = SProps.Mass();
1016 if (aShape.ShapeType() < TopAbs_SHELL) {
1017 for (TopExp_Explorer Exp (aShape, TopAbs_SOLID); Exp.More(); Exp.Next()) {
1018 GProp_GProps VProps;
1019 BRepGProp::VolumeProperties(Exp.Current(), VProps);
1020 theVolume += VProps.Mass();
1024 catch (Standard_Failure) {
1025 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1026 SetErrorCode(aFail->GetMessageString());
1033 //=============================================================================
1037 //=============================================================================
1038 void GEOMImpl_IMeasureOperations::GetInertia
1039 (Handle(GEOM_Object) theShape,
1040 Standard_Real& I11, Standard_Real& I12, Standard_Real& I13,
1041 Standard_Real& I21, Standard_Real& I22, Standard_Real& I23,
1042 Standard_Real& I31, Standard_Real& I32, Standard_Real& I33,
1043 Standard_Real& Ix , Standard_Real& Iy , Standard_Real& Iz)
1047 if (theShape.IsNull()) return;
1049 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1050 if (aRefShape.IsNull()) return;
1052 TopoDS_Shape aShape = aRefShape->GetValue();
1053 if (aShape.IsNull()) {
1054 SetErrorCode("The Objects has NULL Shape");
1058 //Compute the parameters
1059 GProp_GProps System;
1062 #if OCC_VERSION_LARGE > 0x06010000
1065 if (aShape.ShapeType() == TopAbs_VERTEX ||
1066 aShape.ShapeType() == TopAbs_EDGE ||
1067 aShape.ShapeType() == TopAbs_WIRE) {
1068 BRepGProp::LinearProperties(aShape, System);
1069 } else if (aShape.ShapeType() == TopAbs_FACE ||
1070 aShape.ShapeType() == TopAbs_SHELL) {
1071 BRepGProp::SurfaceProperties(aShape, System);
1073 BRepGProp::VolumeProperties(aShape, System);
1075 gp_Mat I = System.MatrixOfInertia();
1089 GProp_PrincipalProps Pr = System.PrincipalProperties();
1090 Pr.Moments(Ix,Iy,Iz);
1092 catch (Standard_Failure) {
1093 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1094 SetErrorCode(aFail->GetMessageString());
1101 //=============================================================================
1105 //=============================================================================
1106 void GEOMImpl_IMeasureOperations::GetBoundingBox
1107 (Handle(GEOM_Object) theShape,
1108 const Standard_Boolean precise,
1109 Standard_Real& Xmin, Standard_Real& Xmax,
1110 Standard_Real& Ymin, Standard_Real& Ymax,
1111 Standard_Real& Zmin, Standard_Real& Zmax)
1115 if (theShape.IsNull()) return;
1117 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1118 if (aRefShape.IsNull()) return;
1120 TopoDS_Shape aShape = aRefShape->GetValue();
1121 if (aShape.IsNull()) {
1122 SetErrorCode("The Objects has NULL Shape");
1126 //Compute the parameters
1130 #if OCC_VERSION_LARGE > 0x06010000
1133 BRepBuilderAPI_Copy aCopyTool (aShape);
1134 if (!aCopyTool.IsDone()) {
1135 SetErrorCode("GetBoundingBox Error: Bad shape detected");
1139 aShape = aCopyTool.Shape();
1141 // remove triangulation to obtain more exact boundaries
1142 BRepTools::Clean(aShape);
1144 BRepBndLib::Add(aShape, B);
1147 if (!GEOMUtils::PreciseBoundingBox(aShape, B)) {
1148 SetErrorCode("GetBoundingBox Error: Bounding box cannot be precised");
1153 B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
1155 catch (Standard_Failure) {
1156 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1157 SetErrorCode(aFail->GetMessageString());
1164 //=============================================================================
1168 //=============================================================================
1169 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
1170 (Handle(GEOM_Object) theShape,
1171 const Standard_Boolean precise)
1175 if (theShape.IsNull()) return NULL;
1177 //Add a new BoundingBox object
1178 Handle(GEOM_Object) aBnd = GetEngine()->AddObject(GetDocID(), GEOM_BOX);
1180 //Add a new BoundingBox function
1181 const int aType = (precise ? BND_BOX_MEASURE_PRECISE : BND_BOX_MEASURE);
1182 Handle(GEOM_Function) aFunction =
1183 aBnd->AddFunction(GEOMImpl_MeasureDriver::GetID(), aType);
1184 if (aFunction.IsNull()) return NULL;
1186 //Check if the function is set correctly
1187 if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
1189 GEOMImpl_IMeasure aCI (aFunction);
1191 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1192 if (aRefShape.IsNull()) return NULL;
1194 aCI.SetBase(aRefShape);
1196 //Compute the BoundingBox value
1198 #if OCC_VERSION_LARGE > 0x06010000
1201 if (!GetSolver()->ComputeFunction(aFunction)) {
1202 SetErrorCode("Measure driver failed to compute a bounding box");
1206 catch (Standard_Failure) {
1207 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1208 SetErrorCode(aFail->GetMessageString());
1212 //Make a Python command
1213 GEOM::TPythonDump aPd(aFunction);
1215 aPd << aBnd << " = geompy.MakeBoundingBox(" << theShape;
1227 //=============================================================================
1231 //=============================================================================
1232 void GEOMImpl_IMeasureOperations::GetTolerance
1233 (Handle(GEOM_Object) theShape,
1234 Standard_Real& FaceMin, Standard_Real& FaceMax,
1235 Standard_Real& EdgeMin, Standard_Real& EdgeMax,
1236 Standard_Real& VertMin, Standard_Real& VertMax)
1240 if (theShape.IsNull()) return;
1242 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1243 if (aRefShape.IsNull()) return;
1245 TopoDS_Shape aShape = aRefShape->GetValue();
1246 if (aShape.IsNull()) {
1247 SetErrorCode("The Objects has NULL Shape");
1251 //Compute the parameters
1253 FaceMin = EdgeMin = VertMin = RealLast();
1254 FaceMax = EdgeMax = VertMax = -RealLast();
1257 #if OCC_VERSION_LARGE > 0x06010000
1260 for (TopExp_Explorer ExF (aShape, TopAbs_FACE); ExF.More(); ExF.Next()) {
1261 TopoDS_Face Face = TopoDS::Face(ExF.Current());
1262 T = BRep_Tool::Tolerance(Face);
1268 for (TopExp_Explorer ExE (aShape, TopAbs_EDGE); ExE.More(); ExE.Next()) {
1269 TopoDS_Edge Edge = TopoDS::Edge(ExE.Current());
1270 T = BRep_Tool::Tolerance(Edge);
1276 for (TopExp_Explorer ExV (aShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1277 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
1278 T = BRep_Tool::Tolerance(Vertex);
1285 catch (Standard_Failure) {
1286 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1287 SetErrorCode(aFail->GetMessageString());
1294 //=============================================================================
1298 //=============================================================================
1299 bool GEOMImpl_IMeasureOperations::CheckShape (Handle(GEOM_Object) theShape,
1300 const Standard_Boolean theIsCheckGeom,
1301 TCollection_AsciiString& theDump)
1305 if (theShape.IsNull()) return false;
1307 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1308 if (aRefShape.IsNull()) return false;
1310 TopoDS_Shape aShape = aRefShape->GetValue();
1311 if (aShape.IsNull()) {
1312 SetErrorCode("The Objects has NULL Shape");
1316 //Compute the parameters
1317 bool isValid = false;
1319 #if OCC_VERSION_LARGE > 0x06010000
1322 BRepCheck_Analyzer ana (aShape, theIsCheckGeom);
1323 if (ana.IsValid()) {
1327 StructuralDump(ana, aShape, theDump);
1330 catch (Standard_Failure) {
1331 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1332 SetErrorCode(aFail->GetMessageString());
1340 //=============================================================================
1342 * CheckSelfIntersections
1344 //=============================================================================
1345 bool GEOMImpl_IMeasureOperations::CheckSelfIntersections
1346 (Handle(GEOM_Object) theShape,
1347 Handle(TColStd_HSequenceOfInteger)& theIntersections)
1350 bool isGood = false;
1352 if (theIntersections.IsNull())
1353 theIntersections = new TColStd_HSequenceOfInteger;
1355 theIntersections->Clear();
1357 if (theShape.IsNull())
1360 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1361 if (aRefShape.IsNull()) return isGood;
1363 TopoDS_Shape aShape = aRefShape->GetValue();
1364 if (aShape.IsNull()) return isGood;
1368 TopoDS_Compound aCS;
1369 TopoDS_Shape aScopy;
1371 GEOMAlgo_AlgoTools::CopyShape(aShape, aScopy);
1373 // Map sub-shapes and their indices
1374 TopTools_IndexedMapOfShape anIndices;
1375 TopExp::MapShapes(aScopy, anIndices);
1377 aBB.MakeCompound(aCS);
1378 aBB.Add(aCS, aScopy);
1380 BOPCol_ListOfShape aLCS;
1381 aLCS.Append(aScopy);
1383 BOPAlgo_CheckerSI aCSI; // checker of self-interferences
1384 aCSI.SetArguments(aLCS);
1386 // 1. Launch the checker
1388 Standard_Integer iErr = aCSI.ErrorStatus();
1390 return false; // Error
1395 Standard_Integer aNbS, n1, n2;
1396 BOPDS_MapIteratorMapOfPassKey aItMPK;
1398 // 2. Take the shapes from DS
1399 const BOPDS_DS& aDS = aCSI.DS();
1400 aNbS=aDS.NbShapes();
1402 // 3. Get the pairs of interfered shapes
1403 const BOPDS_MapOfPassKey& aMPK=aDS.Interferences();
1404 aItMPK.Initialize(aMPK);
1405 for (; aItMPK.More(); aItMPK.Next()) {
1406 const BOPDS_PassKey& aPK=aItMPK.Value();
1409 if (n1 > aNbS || n2 > aNbS){
1410 return false; // Error
1412 const TopoDS_Shape& aS1 = aDS.Shape(n1);
1413 const TopoDS_Shape& aS2 = aDS.Shape(n2);
1415 theIntersections->Append(anIndices.FindIndex(aS1));
1416 theIntersections->Append(anIndices.FindIndex(aS2));
1424 //=============================================================================
1428 //=============================================================================
1429 TCollection_AsciiString GEOMImpl_IMeasureOperations::IsGoodForSolid (Handle(GEOM_Object) theShape)
1433 TCollection_AsciiString aRes = "";
1435 if (theShape.IsNull()) {
1436 aRes = "WRN_NULL_OBJECT_OR_SHAPE";
1439 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1440 if (aRefShape.IsNull()) {
1441 aRes = "WRN_NULL_OBJECT_OR_SHAPE";
1444 TopoDS_Shape aShape = aRefShape->GetValue();
1445 if (aShape.IsNull()) {
1446 aRes = "WRN_NULL_OBJECT_OR_SHAPE";
1449 if (aShape.ShapeType() == TopAbs_COMPOUND) {
1450 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1451 if (It.More()) aShape = It.Value();
1453 if (aShape.ShapeType() == TopAbs_SHELL) {
1454 BRepCheck_Shell chkShell (TopoDS::Shell(aShape));
1455 if (chkShell.Closed() == BRepCheck_NotClosed) {
1456 aRes = "WRN_SHAPE_UNCLOSED";
1460 aRes = "WRN_SHAPE_NOT_SHELL";
1472 //=============================================================================
1476 //=============================================================================
1477 TCollection_AsciiString GEOMImpl_IMeasureOperations::WhatIs (Handle(GEOM_Object) theShape)
1481 TCollection_AsciiString Astr;
1483 if (theShape.IsNull()) return Astr;
1485 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1486 if (aRefShape.IsNull()) return Astr;
1488 TopoDS_Shape aShape = aRefShape->GetValue();
1489 if (aShape.IsNull()) {
1490 SetErrorCode("The Objects has NULL Shape");
1494 //Compute the parameters
1495 if (aShape.ShapeType() == TopAbs_EDGE) {
1496 if (BRep_Tool::Degenerated(TopoDS::Edge(aShape))) {
1497 Astr = Astr + " It is a degenerated edge \n";
1501 Astr = Astr + " Number of sub-shapes : \n";
1504 #if OCC_VERSION_LARGE > 0x06010000
1507 int iType, nbTypes [TopAbs_SHAPE];
1508 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1510 nbTypes[aShape.ShapeType()]++;
1512 TopTools_MapOfShape aMapOfShape;
1513 aMapOfShape.Add(aShape);
1514 TopTools_ListOfShape aListOfShape;
1515 aListOfShape.Append(aShape);
1517 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1518 for (; itL.More(); itL.Next()) {
1519 TopoDS_Iterator it (itL.Value());
1520 for (; it.More(); it.Next()) {
1521 TopoDS_Shape s = it.Value();
1522 if (aMapOfShape.Add(s)) {
1523 aListOfShape.Append(s);
1524 nbTypes[s.ShapeType()]++;
1529 Astr = Astr + " VERTEX : " + TCollection_AsciiString(nbTypes[TopAbs_VERTEX]) + "\n";
1530 Astr = Astr + " EDGE : " + TCollection_AsciiString(nbTypes[TopAbs_EDGE]) + "\n";
1531 Astr = Astr + " WIRE : " + TCollection_AsciiString(nbTypes[TopAbs_WIRE]) + "\n";
1532 Astr = Astr + " FACE : " + TCollection_AsciiString(nbTypes[TopAbs_FACE]) + "\n";
1533 Astr = Astr + " SHELL : " + TCollection_AsciiString(nbTypes[TopAbs_SHELL]) + "\n";
1534 Astr = Astr + " SOLID : " + TCollection_AsciiString(nbTypes[TopAbs_SOLID]) + "\n";
1535 Astr = Astr + " COMPSOLID : " + TCollection_AsciiString(nbTypes[TopAbs_COMPSOLID]) + "\n";
1536 Astr = Astr + " COMPOUND : " + TCollection_AsciiString(nbTypes[TopAbs_COMPOUND]) + "\n";
1537 Astr = Astr + " SHAPE : " + TCollection_AsciiString(aMapOfShape.Extent());
1539 catch (Standard_Failure) {
1540 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1541 SetErrorCode(aFail->GetMessageString());
1549 //=============================================================================
1553 //=============================================================================
1554 std::vector<bool> GEOMImpl_IMeasureOperations::AreCoordsInside(Handle(GEOM_Object) theShape,
1555 const std::vector<double>& coords,
1558 std::vector<bool> res;
1559 if (!theShape.IsNull()) {
1560 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1561 if (!aRefShape.IsNull()) {
1562 TopoDS_Shape aShape = aRefShape->GetValue();
1563 if (!aShape.IsNull()) {
1564 unsigned int nb_points = coords.size()/3;
1565 for (int i = 0; i < nb_points; i++) {
1566 double x = coords[3*i];
1567 double y = coords[3*i+1];
1568 double z = coords[3*i+2];
1569 gp_Pnt aPnt(x, y, z);
1570 if ( aShape.ShapeType() == TopAbs_COMPOUND || aShape.ShapeType() == TopAbs_COMPSOLID ||
1571 aShape.ShapeType() == TopAbs_SOLID ) {
1572 TopExp_Explorer anExp;
1573 bool isFound = false;
1574 for ( anExp.Init( aShape, TopAbs_SOLID ); anExp.More() && !isFound; anExp.Next() ) {
1575 BRepClass3d_SolidClassifier SC( anExp.Current() );
1576 SC.Perform( aPnt, tolerance );
1577 isFound = ( SC.State() == TopAbs_IN ) || ( SC.State() == TopAbs_ON );
1579 res.push_back( isFound );
1582 res.push_back( false );
1590 //=============================================================================
1594 //=============================================================================
1595 Standard_Real GEOMImpl_IMeasureOperations::GetMinDistance
1596 (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2,
1597 Standard_Real& X1, Standard_Real& Y1, Standard_Real& Z1,
1598 Standard_Real& X2, Standard_Real& Y2, Standard_Real& Z2)
1601 Standard_Real MinDist = 1.e9;
1603 if (theShape1.IsNull() || theShape2.IsNull()) return MinDist;
1605 Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction();
1606 Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction();
1607 if (aRefShape1.IsNull() || aRefShape2.IsNull()) return MinDist;
1609 TopoDS_Shape aShape1 = aRefShape1->GetValue();
1610 TopoDS_Shape aShape2 = aRefShape2->GetValue();
1611 if (aShape1.IsNull() || aShape2.IsNull()) {
1612 SetErrorCode("One of Objects has NULL Shape");
1616 //Compute the parameters
1618 #if OCC_VERSION_LARGE > 0x06010000
1622 gp_Pnt aPnt1, aPnt2;
1624 MinDist = GEOMUtils::GetMinDistance(aShape1, aShape2, aPnt1, aPnt2);
1626 if (MinDist >= 0.0) {
1627 aPnt1.Coord(X1, Y1, Z1);
1628 aPnt2.Coord(X2, Y2, Z2);
1633 catch (Standard_Failure) {
1634 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1635 SetErrorCode(aFail->GetMessageString());
1643 //=======================================================================
1645 * Get coordinates of closest points of two shapes
1647 //=======================================================================
1648 Standard_Integer GEOMImpl_IMeasureOperations::ClosestPoints (Handle(GEOM_Object) theShape1,
1649 Handle(GEOM_Object) theShape2,
1650 Handle(TColStd_HSequenceOfReal)& theDoubles)
1653 Standard_Integer nbSolutions = 0;
1655 if (theShape1.IsNull() || theShape2.IsNull()) return nbSolutions;
1657 Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction();
1658 Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction();
1659 if (aRefShape1.IsNull() || aRefShape2.IsNull()) return nbSolutions;
1661 TopoDS_Shape aShape1 = aRefShape1->GetValue();
1662 TopoDS_Shape aShape2 = aRefShape2->GetValue();
1663 if (aShape1.IsNull() || aShape2.IsNull()) {
1664 SetErrorCode("One of Objects has NULL Shape");
1668 // Compute the extremities
1670 #if OCC_VERSION_LARGE > 0x06010000
1675 // additional workaround for bugs 19899, 19908 and 19910 from Mantis
1677 double dist = GEOMUtils::GetMinDistanceSingular(aShape1, aShape2, P1, P2);
1681 theDoubles->Append(P1.X());
1682 theDoubles->Append(P1.Y());
1683 theDoubles->Append(P1.Z());
1684 theDoubles->Append(P2.X());
1685 theDoubles->Append(P2.Y());
1686 theDoubles->Append(P2.Z());
1692 BRepExtrema_DistShapeShape dst (aShape1, aShape2);
1694 nbSolutions = dst.NbSolution();
1695 if (theDoubles.IsNull()) theDoubles = new TColStd_HSequenceOfReal;
1698 for (int i = 1; i <= nbSolutions; i++) {
1699 P1 = dst.PointOnShape1(i);
1700 P2 = dst.PointOnShape2(i);
1702 theDoubles->Append(P1.X());
1703 theDoubles->Append(P1.Y());
1704 theDoubles->Append(P1.Z());
1705 theDoubles->Append(P2.X());
1706 theDoubles->Append(P2.Y());
1707 theDoubles->Append(P2.Z());
1711 catch (Standard_Failure) {
1712 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1713 SetErrorCode(aFail->GetMessageString());
1721 //=======================================================================
1723 * Get coordinates of point
1725 //=======================================================================
1726 void GEOMImpl_IMeasureOperations::PointCoordinates (Handle(GEOM_Object) theShape,
1727 Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ)
1731 if (theShape.IsNull())
1734 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1735 if (aRefShape.IsNull())
1738 TopoDS_Shape aShape = aRefShape->GetValue();
1739 if (aShape.IsNull() || aShape.ShapeType() != TopAbs_VERTEX)
1741 SetErrorCode( "Shape must be a vertex" );
1746 #if OCC_VERSION_LARGE > 0x06010000
1749 gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
1756 catch (Standard_Failure)
1758 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1759 SetErrorCode( aFail->GetMessageString() );
1763 //=======================================================================
1765 * Compute angle (in degrees) between two lines
1767 //=======================================================================
1768 Standard_Real GEOMImpl_IMeasureOperations::GetAngle (Handle(GEOM_Object) theLine1,
1769 Handle(GEOM_Object) theLine2)
1771 if (theLine1->GetType() == GEOM_VECTOR &&
1772 theLine2->GetType() == GEOM_VECTOR)
1773 return GetAngleBtwVectors(theLine1, theLine2);
1777 Standard_Real anAngle = -1.0;
1779 if (theLine1.IsNull() || theLine2.IsNull())
1782 Handle(GEOM_Function) aRefLine1 = theLine1->GetLastFunction();
1783 Handle(GEOM_Function) aRefLine2 = theLine2->GetLastFunction();
1784 if (aRefLine1.IsNull() || aRefLine2.IsNull())
1787 TopoDS_Shape aLine1 = aRefLine1->GetValue();
1788 TopoDS_Shape aLine2 = aRefLine2->GetValue();
1789 if (aLine1.IsNull() || aLine2.IsNull() ||
1790 aLine1.ShapeType() != TopAbs_EDGE ||
1791 aLine2.ShapeType() != TopAbs_EDGE)
1793 SetErrorCode("Two edges must be given");
1798 #if OCC_VERSION_LARGE > 0x06010000
1801 TopoDS_Edge E1 = TopoDS::Edge(aLine1);
1802 TopoDS_Edge E2 = TopoDS::Edge(aLine2);
1805 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
1806 Handle(Geom_Curve) C2 = BRep_Tool::Curve(E2,fp,lp);
1808 if ( C1.IsNull() || C2.IsNull() ||
1809 !C1->IsKind(STANDARD_TYPE(Geom_Line)) ||
1810 !C2->IsKind(STANDARD_TYPE(Geom_Line)))
1812 SetErrorCode("The edges must be linear");
1816 Handle(Geom_Line) L1 = Handle(Geom_Line)::DownCast(C1);
1817 Handle(Geom_Line) L2 = Handle(Geom_Line)::DownCast(C2);
1819 gp_Lin aLin1 = L1->Lin();
1820 gp_Lin aLin2 = L2->Lin();
1822 anAngle = aLin1.Angle(aLin2);
1823 anAngle *= 180. / M_PI; // convert radians into degrees
1825 if (anAngle > 90.0) {
1826 anAngle = 180.0 - anAngle;
1831 catch (Standard_Failure)
1833 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1834 SetErrorCode(aFail->GetMessageString());
1840 //=======================================================================
1842 * Compute angle (in degrees) between two vectors
1844 //=======================================================================
1845 Standard_Real GEOMImpl_IMeasureOperations::GetAngleBtwVectors (Handle(GEOM_Object) theVec1,
1846 Handle(GEOM_Object) theVec2)
1850 Standard_Real anAngle = -1.0;
1852 if (theVec1.IsNull() || theVec2.IsNull())
1855 if (theVec1->GetType() != GEOM_VECTOR || theVec2->GetType() != GEOM_VECTOR) {
1856 SetErrorCode("Two vectors must be given");
1860 Handle(GEOM_Function) aRefVec1 = theVec1->GetLastFunction();
1861 Handle(GEOM_Function) aRefVec2 = theVec2->GetLastFunction();
1862 if (aRefVec1.IsNull() || aRefVec2.IsNull())
1865 TopoDS_Shape aVec1 = aRefVec1->GetValue();
1866 TopoDS_Shape aVec2 = aRefVec2->GetValue();
1867 if (aVec1.IsNull() || aVec2.IsNull() ||
1868 aVec1.ShapeType() != TopAbs_EDGE ||
1869 aVec2.ShapeType() != TopAbs_EDGE)
1871 SetErrorCode("Two edges must be given");
1876 #if OCC_VERSION_LARGE > 0x06010000
1879 TopoDS_Edge aE1 = TopoDS::Edge(aVec1);
1880 TopoDS_Edge aE2 = TopoDS::Edge(aVec2);
1882 TopoDS_Vertex aP11, aP12, aP21, aP22;
1883 TopExp::Vertices(aE1, aP11, aP12, Standard_True);
1884 TopExp::Vertices(aE2, aP21, aP22, Standard_True);
1885 if (aP11.IsNull() || aP12.IsNull() || aP21.IsNull() || aP22.IsNull()) {
1886 SetErrorCode("Bad edge given");
1890 gp_Vec aV1 (BRep_Tool::Pnt(aP11), BRep_Tool::Pnt(aP12));
1891 gp_Vec aV2 (BRep_Tool::Pnt(aP21), BRep_Tool::Pnt(aP22)) ;
1893 anAngle = aV1.Angle(aV2);
1894 anAngle *= 180. / M_PI; // convert radians into degrees
1898 catch (Standard_Failure)
1900 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1901 SetErrorCode(aFail->GetMessageString());
1908 //=============================================================================
1910 * CurveCurvatureByParam
1912 //=============================================================================
1913 Standard_Real GEOMImpl_IMeasureOperations::CurveCurvatureByParam
1914 (Handle(GEOM_Object) theCurve, Standard_Real& theParam)
1917 Standard_Real aRes = -1.0;
1919 if(theCurve.IsNull()) return aRes;
1921 Handle(GEOM_Function) aRefShape = theCurve->GetLastFunction();
1922 if(aRefShape.IsNull()) return aRes;
1924 TopoDS_Shape aShape = aRefShape->GetValue();
1925 if(aShape.IsNull()) {
1926 SetErrorCode("One of Objects has NULL Shape");
1930 Standard_Real aFP, aLP, aP;
1931 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aShape), aFP, aLP);
1932 aP = aFP + (aLP - aFP) * theParam;
1934 if(aCurve.IsNull()) return aRes;
1938 #if OCC_VERSION_LARGE > 0x06010000
1941 GeomLProp_CLProps Prop = GeomLProp_CLProps
1942 (aCurve, aP, 2, Precision::Confusion());
1943 aRes = fabs(Prop.Curvature());
1946 catch (Standard_Failure) {
1947 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1948 SetErrorCode(aFail->GetMessageString());
1952 if( aRes > Precision::Confusion() )
1961 //=============================================================================
1963 * CurveCurvatureByPoint
1965 //=============================================================================
1966 Standard_Real GEOMImpl_IMeasureOperations::CurveCurvatureByPoint
1967 (Handle(GEOM_Object) theCurve, Handle(GEOM_Object) thePoint)
1970 Standard_Real aRes = -1.0;
1972 if( theCurve.IsNull() || thePoint.IsNull() ) return aRes;
1974 Handle(GEOM_Function) aRefCurve = theCurve->GetLastFunction();
1975 Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction();
1976 if( aRefCurve.IsNull() || aRefPoint.IsNull() ) return aRes;
1978 TopoDS_Edge anEdge = TopoDS::Edge(aRefCurve->GetValue());
1979 TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue());
1980 if( anEdge.IsNull() || aPnt.IsNull() ) {
1981 SetErrorCode("One of Objects has NULL Shape");
1985 Standard_Real aFP, aLP;
1986 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFP, aLP);
1987 if(aCurve.IsNull()) return aRes;
1988 gp_Pnt aPoint = BRep_Tool::Pnt(aPnt);
1992 #if OCC_VERSION_LARGE > 0x06010000
1995 GeomAPI_ProjectPointOnCurve PPCurve(aPoint, aCurve, aFP, aLP);
1996 if(PPCurve.NbPoints()>0) {
1997 GeomLProp_CLProps Prop = GeomLProp_CLProps
1998 (aCurve, PPCurve.LowerDistanceParameter(), 2, Precision::Confusion());
1999 aRes = fabs(Prop.Curvature());
2003 catch (Standard_Failure) {
2004 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2005 SetErrorCode(aFail->GetMessageString());
2009 if( aRes > Precision::Confusion() )
2018 //=============================================================================
2020 * getSurfaceCurvatures
2022 //=============================================================================
2023 Standard_Real GEOMImpl_IMeasureOperations::getSurfaceCurvatures
2024 (const Handle(Geom_Surface)& aSurf,
2025 Standard_Real theUParam,
2026 Standard_Real theVParam,
2027 Standard_Boolean theNeedMaxCurv)
2030 Standard_Real aRes = 1.0;
2032 if (aSurf.IsNull()) return aRes;
2035 #if OCC_VERSION_LARGE > 0x06010000
2038 GeomLProp_SLProps Prop = GeomLProp_SLProps
2039 (aSurf, theUParam, theVParam, 2, Precision::Confusion());
2040 if(Prop.IsCurvatureDefined()) {
2041 if(Prop.IsUmbilic()) {
2042 //cout<<"is umbilic"<<endl;
2043 aRes = fabs(Prop.MeanCurvature());
2046 //cout<<"is not umbilic"<<endl;
2047 double c1 = fabs(Prop.MaxCurvature());
2048 double c2 = fabs(Prop.MinCurvature());
2057 catch (Standard_Failure) {
2058 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2059 SetErrorCode(aFail->GetMessageString());
2063 if( fabs(aRes) > Precision::Confusion() )
2072 //=============================================================================
2074 * MaxSurfaceCurvatureByParam
2076 //=============================================================================
2077 Standard_Real GEOMImpl_IMeasureOperations::MaxSurfaceCurvatureByParam
2078 (Handle(GEOM_Object) theSurf,
2079 Standard_Real& theUParam,
2080 Standard_Real& theVParam)
2083 Standard_Real aRes = -1.0;
2085 if (theSurf.IsNull()) return aRes;
2087 Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
2088 if(aRefShape.IsNull()) return aRes;
2090 TopoDS_Shape aShape = aRefShape->GetValue();
2091 if(aShape.IsNull()) {
2092 SetErrorCode("One of Objects has NULL Shape");
2096 TopoDS_Face F = TopoDS::Face(aShape);
2097 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
2099 //Compute the parameters
2100 Standard_Real U1,U2,V1,V2;
2101 ShapeAnalysis::GetFaceUVBounds(F,U1,U2,V1,V2);
2102 Standard_Real U = U1 + (U2-U1)*theUParam;
2103 Standard_Real V = V1 + (V2-V1)*theVParam;
2105 return getSurfaceCurvatures(aSurf, U, V, true);
2109 //=============================================================================
2111 * MaxSurfaceCurvatureByPoint
2113 //=============================================================================
2114 Standard_Real GEOMImpl_IMeasureOperations::MaxSurfaceCurvatureByPoint
2115 (Handle(GEOM_Object) theSurf, Handle(GEOM_Object) thePoint)
2118 Standard_Real aRes = -1.0;
2120 if( theSurf.IsNull() || thePoint.IsNull() ) return aRes;
2122 Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
2123 Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction();
2124 if( aRefShape.IsNull() || aRefPoint.IsNull() ) return aRes;
2126 TopoDS_Face aFace = TopoDS::Face(aRefShape->GetValue());
2127 TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue());
2128 if( aFace.IsNull() || aPnt.IsNull() ) {
2129 SetErrorCode("One of Objects has NULL Shape");
2133 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
2134 if(aSurf.IsNull()) return aRes;
2135 gp_Pnt aPoint = BRep_Tool::Pnt(aPnt);
2137 //Compute the parameters
2138 ShapeAnalysis_Surface sas(aSurf);
2139 gp_Pnt2d UV = sas.ValueOfUV(aPoint,Precision::Confusion());
2141 return getSurfaceCurvatures(aSurf, UV.X(), UV.Y(), true);
2145 //=============================================================================
2147 * MinSurfaceCurvatureByParam
2149 //=============================================================================
2150 Standard_Real GEOMImpl_IMeasureOperations::MinSurfaceCurvatureByParam
2151 (Handle(GEOM_Object) theSurf,
2152 Standard_Real& theUParam,
2153 Standard_Real& theVParam)
2156 Standard_Real aRes = -1.0;
2158 if (theSurf.IsNull()) return aRes;
2160 Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
2161 if(aRefShape.IsNull()) return aRes;
2163 TopoDS_Shape aShape = aRefShape->GetValue();
2164 if(aShape.IsNull()) {
2165 SetErrorCode("One of Objects has NULL Shape");
2169 TopoDS_Face F = TopoDS::Face(aShape);
2170 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
2172 //Compute the parameters
2173 Standard_Real U1,U2,V1,V2;
2174 ShapeAnalysis::GetFaceUVBounds(F,U1,U2,V1,V2);
2175 Standard_Real U = U1 + (U2-U1)*theUParam;
2176 Standard_Real V = V1 + (V2-V1)*theVParam;
2178 return getSurfaceCurvatures(aSurf, U, V, false);
2182 //=============================================================================
2184 * MinSurfaceCurvatureByPoint
2186 //=============================================================================
2187 Standard_Real GEOMImpl_IMeasureOperations::MinSurfaceCurvatureByPoint
2188 (Handle(GEOM_Object) theSurf, Handle(GEOM_Object) thePoint)
2191 Standard_Real aRes = -1.0;
2193 if( theSurf.IsNull() || thePoint.IsNull() ) return aRes;
2195 Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
2196 Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction();
2197 if( aRefShape.IsNull() || aRefPoint.IsNull() ) return aRes;
2199 TopoDS_Face aFace = TopoDS::Face(aRefShape->GetValue());
2200 TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue());
2201 if( aFace.IsNull() || aPnt.IsNull() ) {
2202 SetErrorCode("One of Objects has NULL Shape");
2206 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
2207 if(aSurf.IsNull()) return aRes;
2208 gp_Pnt aPoint = BRep_Tool::Pnt(aPnt);
2210 //Compute the parameters
2211 ShapeAnalysis_Surface sas(aSurf);
2212 gp_Pnt2d UV = sas.ValueOfUV(aPoint,Precision::Confusion());
2214 return getSurfaceCurvatures(aSurf, UV.X(), UV.Y(), false);
2218 //=======================================================================
2219 //function : StructuralDump
2220 //purpose : Structural (data exchange) style of output.
2221 //=======================================================================
2222 void GEOMImpl_IMeasureOperations::StructuralDump (const BRepCheck_Analyzer& theAna,
2223 const TopoDS_Shape& theShape,
2224 TCollection_AsciiString& theDump)
2228 theDump += " -- The Shape has problems :\n";
2229 theDump += " Check Count\n";
2230 theDump += " ------------------------------------------------\n";
2232 Standard_Integer last_stat = (Standard_Integer)BRepCheck_CheckFail;
2233 Handle(TColStd_HArray1OfInteger) NbProblems =
2234 new TColStd_HArray1OfInteger(1, last_stat);
2235 for (i = 1; i <= last_stat; i++)
2236 NbProblems->SetValue(i,0);
2238 Handle(TopTools_HSequenceOfShape) sl;
2239 sl = new TopTools_HSequenceOfShape();
2240 TopTools_DataMapOfShapeListOfShape theMap;
2242 GetProblemShapes(theAna, theShape, sl, NbProblems, theMap);
2245 Standard_Integer count = 0;
2246 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnCurve);
2248 theDump += " Invalid Point on Curve ................... ";
2249 theDump += TCollection_AsciiString(count) + "\n";
2251 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnCurveOnSurface);
2253 theDump += " Invalid Point on CurveOnSurface .......... ";
2254 theDump += TCollection_AsciiString(count) + "\n";
2256 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnSurface);
2258 theDump += " Invalid Point on Surface ................. ";
2259 theDump += TCollection_AsciiString(count) + "\n";
2261 count = NbProblems->Value((Standard_Integer)BRepCheck_No3DCurve);
2263 theDump += " No 3D Curve .............................. ";
2264 theDump += TCollection_AsciiString(count) + "\n";
2266 count = NbProblems->Value((Standard_Integer)BRepCheck_Multiple3DCurve);
2268 theDump += " Multiple 3D Curve ........................ ";
2269 theDump += TCollection_AsciiString(count) + "\n";
2271 count = NbProblems->Value((Standard_Integer)BRepCheck_Invalid3DCurve);
2273 theDump += " Invalid 3D Curve ......................... ";
2274 theDump += TCollection_AsciiString(count) + "\n";
2276 count = NbProblems->Value((Standard_Integer)BRepCheck_NoCurveOnSurface);
2278 theDump += " No Curve on Surface ...................... ";
2279 theDump += TCollection_AsciiString(count) + "\n";
2281 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidCurveOnSurface);
2283 theDump += " Invalid Curve on Surface ................. ";
2284 theDump += TCollection_AsciiString(count) + "\n";
2286 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidCurveOnClosedSurface);
2288 theDump += " Invalid Curve on closed Surface .......... ";
2289 theDump += TCollection_AsciiString(count) + "\n";
2291 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidSameRangeFlag);
2293 theDump += " Invalid SameRange Flag ................... ";
2294 theDump += TCollection_AsciiString(count) + "\n";
2296 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidSameParameterFlag);
2298 theDump += " Invalid SameParameter Flag ............... ";
2299 theDump += TCollection_AsciiString(count) + "\n";
2301 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidDegeneratedFlag);
2303 theDump += " Invalid Degenerated Flag ................. ";
2304 theDump += TCollection_AsciiString(count) + "\n";
2306 count = NbProblems->Value((Standard_Integer)BRepCheck_FreeEdge);
2308 theDump += " Free Edge ................................ ";
2309 theDump += TCollection_AsciiString(count) + "\n";
2311 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidMultiConnexity);
2313 theDump += " Invalid MultiConnexity ................... ";
2314 theDump += TCollection_AsciiString(count) + "\n";
2316 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidRange);
2318 theDump += " Invalid Range ............................ ";
2319 theDump += TCollection_AsciiString(count) + "\n";
2321 count = NbProblems->Value((Standard_Integer)BRepCheck_EmptyWire);
2323 theDump += " Empty Wire ............................... ";
2324 theDump += TCollection_AsciiString(count) + "\n";
2326 count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantEdge);
2328 theDump += " Redundant Edge ........................... ";
2329 theDump += TCollection_AsciiString(count) + "\n";
2331 count = NbProblems->Value((Standard_Integer)BRepCheck_SelfIntersectingWire);
2333 theDump += " Self Intersecting Wire ................... ";
2334 theDump += TCollection_AsciiString(count) + "\n";
2336 count = NbProblems->Value((Standard_Integer)BRepCheck_NoSurface);
2338 theDump += " No Surface ............................... ";
2339 theDump += TCollection_AsciiString(count) + "\n";
2341 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidWire);
2343 theDump += " Invalid Wire ............................. ";
2344 theDump += TCollection_AsciiString(count) + "\n";
2346 count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantWire);
2348 theDump += " Redundant Wire ........................... ";
2349 theDump += TCollection_AsciiString(count) + "\n";
2351 count = NbProblems->Value((Standard_Integer)BRepCheck_IntersectingWires);
2353 theDump += " Intersecting Wires ....................... ";
2354 theDump += TCollection_AsciiString(count) + "\n";
2356 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidImbricationOfWires);
2358 theDump += " Invalid Imbrication of Wires ............. ";
2359 theDump += TCollection_AsciiString(count) + "\n";
2361 count = NbProblems->Value((Standard_Integer)BRepCheck_EmptyShell);
2363 theDump += " Empty Shell .............................. ";
2364 theDump += TCollection_AsciiString(count) + "\n";
2366 count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantFace);
2368 theDump += " Redundant Face ........................... ";
2369 theDump += TCollection_AsciiString(count) + "\n";
2371 count = NbProblems->Value((Standard_Integer)BRepCheck_UnorientableShape);
2373 theDump += " Unorientable Shape ....................... ";
2374 theDump += TCollection_AsciiString(count) + "\n";
2376 count = NbProblems->Value((Standard_Integer)BRepCheck_NotClosed);
2378 theDump += " Not Closed ............................... ";
2379 theDump += TCollection_AsciiString(count) + "\n";
2381 count = NbProblems->Value((Standard_Integer)BRepCheck_NotConnected);
2383 theDump += " Not Connected ............................ ";
2384 theDump += TCollection_AsciiString(count) + "\n";
2386 count = NbProblems->Value((Standard_Integer)BRepCheck_SubshapeNotInShape);
2388 theDump += " Sub-shape not in Shape .................... ";
2389 theDump += TCollection_AsciiString(count) + "\n";
2391 count = NbProblems->Value((Standard_Integer)BRepCheck_BadOrientation);
2393 theDump += " Bad Orientation .......................... ";
2394 theDump += TCollection_AsciiString(count) + "\n";
2396 count = NbProblems->Value((Standard_Integer)BRepCheck_BadOrientationOfSubshape);
2398 theDump += " Bad Orientation of Sub-shape .............. ";
2399 theDump += TCollection_AsciiString(count) + "\n";
2401 count = NbProblems->Value((Standard_Integer)BRepCheck_CheckFail);
2403 theDump += " checkshape failure ....................... ";
2404 theDump += TCollection_AsciiString(count) + "\n";
2407 theDump += " ------------------------------------------------\n";
2408 theDump += "*** Shapes with problems : ";
2409 theDump += TCollection_AsciiString(sl->Length()) + "\n";
2411 Standard_Integer nbv, nbe, nbw, nbf, nbs, nbo;
2412 nbv = nbe = nbw = nbf = nbs = nbo = 0;
2414 for (i = 1; i <= sl->Length(); i++) {
2415 TopoDS_Shape shi = sl->Value(i);
2416 TopAbs_ShapeEnum sti = shi.ShapeType();
2418 case TopAbs_VERTEX : nbv++; break;
2419 case TopAbs_EDGE : nbe++; break;
2420 case TopAbs_WIRE : nbw++; break;
2421 case TopAbs_FACE : nbf++; break;
2422 case TopAbs_SHELL : nbs++; break;
2423 case TopAbs_SOLID : nbo++; break;
2429 theDump += "VERTEX : ";
2430 if (nbv < 10) theDump += " ";
2431 theDump += TCollection_AsciiString(nbv) + "\n";
2434 theDump += "EDGE : ";
2435 if (nbe < 10) theDump += " ";
2436 theDump += TCollection_AsciiString(nbe) + "\n";
2439 theDump += "WIRE : ";
2440 if (nbw < 10) theDump += " ";
2441 theDump += TCollection_AsciiString(nbw) + "\n";
2444 theDump += "FACE : ";
2445 if (nbf < 10) theDump += " ";
2446 theDump += TCollection_AsciiString(nbf) + "\n";
2449 theDump += "SHELL : ";
2450 if (nbs < 10) theDump += " ";
2451 theDump += TCollection_AsciiString(nbs) + "\n";
2454 theDump += "SOLID : ";
2455 if (nbo < 10) theDump += " ";
2456 theDump += TCollection_AsciiString(nbo) + "\n";
2461 //=======================================================================
2462 //function : GetProblemShapes
2463 // purpose : for StructuralDump
2464 //=======================================================================
2465 void GEOMImpl_IMeasureOperations::GetProblemShapes (const BRepCheck_Analyzer& theAna,
2466 const TopoDS_Shape& theShape,
2467 Handle(TopTools_HSequenceOfShape)& sl,
2468 Handle(TColStd_HArray1OfInteger)& NbProblems,
2469 TopTools_DataMapOfShapeListOfShape& theMap)
2471 for (TopoDS_Iterator iter(theShape); iter.More(); iter.Next()) {
2472 GetProblemShapes(theAna, iter.Value(), sl, NbProblems, theMap);
2474 TopAbs_ShapeEnum styp = theShape.ShapeType();
2475 BRepCheck_ListIteratorOfListOfStatus itl;
2476 TopTools_ListOfShape empty;
2477 if (!theMap.IsBound(theShape)) {
2478 theMap.Bind(theShape,empty);
2480 if (!theAna.Result(theShape).IsNull()) {
2481 itl.Initialize(theAna.Result(theShape)->Status());
2482 // !!! May be, we have to print all the problems, not only the first one ?
2483 if (itl.Value() != BRepCheck_NoError) {
2484 sl->Append(theShape);
2485 BRepCheck_Status stat = itl.Value();
2486 NbProblems->SetValue((Standard_Integer)stat,
2487 NbProblems->Value((Standard_Integer)stat) + 1);
2494 GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_VERTEX, theMap);
2497 GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_WIRE, theMap);
2498 GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_EDGE, theMap);
2499 GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_VERTEX, theMap);
2504 GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_SHELL, theMap);
2511 //=======================================================================
2512 //function : Contains
2513 //=======================================================================
2514 static Standard_Boolean Contains (const TopTools_ListOfShape& L,
2515 const TopoDS_Shape& S)
2517 TopTools_ListIteratorOfListOfShape it;
2518 for (it.Initialize(L); it.More(); it.Next()) {
2519 if (it.Value().IsSame(S)) {
2520 return Standard_True;
2523 return Standard_False;
2526 //=======================================================================
2527 //function : GetProblemSub
2528 // purpose : for StructuralDump
2529 //=======================================================================
2530 void GEOMImpl_IMeasureOperations::GetProblemSub (const BRepCheck_Analyzer& theAna,
2531 const TopoDS_Shape& theShape,
2532 Handle(TopTools_HSequenceOfShape)& sl,
2533 Handle(TColStd_HArray1OfInteger)& NbProblems,
2534 const TopAbs_ShapeEnum Subtype,
2535 TopTools_DataMapOfShapeListOfShape& theMap)
2537 BRepCheck_ListIteratorOfListOfStatus itl;
2538 TopExp_Explorer exp;
2539 for (exp.Init(theShape, Subtype); exp.More(); exp.Next()) {
2540 const TopoDS_Shape& sub = exp.Current();
2542 const Handle(BRepCheck_Result)& res = theAna.Result(sub);
2543 for (res->InitContextIterator();
2544 res->MoreShapeInContext();
2545 res->NextShapeInContext()) {
2546 if (res->ContextualShape().IsSame(theShape) && !Contains(theMap(sub), theShape)) {
2547 theMap(sub).Append(theShape);
2548 itl.Initialize(res->StatusOnShape());
2550 if (itl.Value() != BRepCheck_NoError) {
2551 Standard_Integer ii = 0;
2553 for (ii = 1; ii <= sl->Length(); ii++)
2554 if (sl->Value(ii).IsSame(sub)) break;
2556 if (ii > sl->Length()) {
2558 BRepCheck_Status stat = itl.Value();
2559 NbProblems->SetValue((Standard_Integer)stat,
2560 NbProblems->Value((Standard_Integer)stat) + 1);
2562 for (ii = 1; ii <= sl->Length(); ii++)
2563 if (sl->Value(ii).IsSame(theShape)) break;
2564 if (ii > sl->Length()) {
2565 sl->Append(theShape);
2566 BRepCheck_Status stat = itl.Value();
2567 NbProblems->SetValue((Standard_Integer)stat,
2568 NbProblems->Value((Standard_Integer)stat) + 1);