1 // Copyright (C) 2007-2008 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
22 #include <Standard_Stream.hxx>
24 #include <GEOMImpl_IMeasureOperations.hxx>
26 #include <GEOMImpl_Types.hxx>
27 #include <GEOMImpl_MeasureDriver.hxx>
28 #include <GEOMImpl_IMeasure.hxx>
30 #include <GEOMAlgo_ShapeInfo.hxx>
31 #include <GEOMAlgo_ShapeInfoFiller.hxx>
33 #include <GEOM_Function.hxx>
34 #include <GEOM_PythonDump.hxx>
36 #include <utilities.h>
38 #include <Utils_ExceptHandlers.hxx>
41 #include <TFunction_DriverTable.hxx>
42 #include <TFunction_Driver.hxx>
43 #include <TFunction_Logbook.hxx>
44 #include <TDF_Tool.hxx>
46 #include <BRep_Tool.hxx>
47 #include <BRepAdaptor_Surface.hxx>
48 #include <BRepBndLib.hxx>
49 #include <BRepCheck.hxx>
50 #include <BRepCheck_Result.hxx>
51 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
52 #include <BRepExtrema_DistShapeShape.hxx>
53 #include <BRepGProp.hxx>
54 #include <BRepTools.hxx>
56 #include <Bnd_Box.hxx>
58 #include <GProp_GProps.hxx>
59 #include <GProp_PrincipalProps.hxx>
63 #include <TopoDS_Edge.hxx>
64 #include <TopoDS_Face.hxx>
65 #include <TopoDS_Shape.hxx>
66 #include <TopoDS_Vertex.hxx>
67 #include <TopoDS_Iterator.hxx>
68 #include <TopExp_Explorer.hxx>
69 #include <TopTools_MapOfShape.hxx>
70 #include <TopTools_ListOfShape.hxx>
71 #include <TopTools_ListIteratorOfListOfShape.hxx>
73 #include <GeomAbs_SurfaceType.hxx>
74 #include <Geom_Surface.hxx>
75 #include <Geom_Plane.hxx>
76 #include <Geom_SphericalSurface.hxx>
77 #include <Geom_CylindricalSurface.hxx>
78 #include <Geom_ToroidalSurface.hxx>
79 #include <Geom_ConicalSurface.hxx>
80 #include <Geom_SurfaceOfLinearExtrusion.hxx>
81 #include <Geom_SurfaceOfRevolution.hxx>
82 #include <Geom_BezierSurface.hxx>
83 #include <Geom_BSplineSurface.hxx>
84 #include <Geom_RectangularTrimmedSurface.hxx>
85 #include <Geom_OffsetSurface.hxx>
86 #include <Geom_Line.hxx>
91 #include <GeomAPI_ProjectPointOnCurve.hxx>
92 #include <ShapeAnalysis.hxx>
93 #include <ShapeAnalysis_Surface.hxx>
94 #include <GeomLProp_CLProps.hxx>
95 #include <GeomLProp_SLProps.hxx>
97 #include <Standard_Failure.hxx>
98 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
100 #include <GeomAPI_IntSS.hxx>
101 #include <Geom_SphericalSurface.hxx>
102 #include <Geom_ToroidalSurface.hxx>
103 #include <Geom_Circle.hxx>
104 #include <BRep_Builder.hxx>
105 #include <TopoDS_Compound.hxx>
106 #include <ShapeFix_Shape.hxx>
109 //=============================================================================
113 //=============================================================================
114 GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations (GEOM_Engine* theEngine, int theDocID)
115 : GEOM_IOperations(theEngine, theDocID)
117 MESSAGE("GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations");
120 //=============================================================================
124 //=============================================================================
125 GEOMImpl_IMeasureOperations::~GEOMImpl_IMeasureOperations()
127 MESSAGE("GEOMImpl_IMeasureOperations::~GEOMImpl_IMeasureOperations");
130 //=============================================================================
131 /*! Get kind and parameters of the given shape.
133 //=============================================================================
134 GEOMImpl_IMeasureOperations::ShapeKind GEOMImpl_IMeasureOperations::KindOfShape
135 (Handle(GEOM_Object) theShape,
136 Handle(TColStd_HSequenceOfInteger)& theIntegers,
137 Handle(TColStd_HSequenceOfReal)& theDoubles)
140 ShapeKind aKind = SK_NO_SHAPE;
142 if (theIntegers.IsNull()) theIntegers = new TColStd_HSequenceOfInteger;
143 else theIntegers->Clear();
145 if (theDoubles.IsNull()) theDoubles = new TColStd_HSequenceOfReal;
146 else theDoubles->Clear();
148 if (theShape.IsNull())
151 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
152 if (aRefShape.IsNull()) return aKind;
154 TopoDS_Shape aShape = aRefShape->GetValue();
155 if (aShape.IsNull()) return aKind;
158 GEOMAlgo_ShapeInfoFiller aSF;
159 aSF.SetShape(aShape);
161 Standard_Integer iErr = aSF.ErrorStatus();
163 SetErrorCode("Error in GEOMAlgo_ShapeInfoFiller");
166 const GEOMAlgo_ShapeInfo& anInfo = aSF.Info();
168 // Interprete results
169 TopAbs_ShapeEnum aType = anInfo.Type();
172 case TopAbs_COMPOUND:
173 case TopAbs_COMPSOLID:
175 // (+) geompy.kind.COMPOUND nb_solids nb_faces nb_edges nb_vertices
176 // (+) geompy.kind.COMPSOLID nb_solids nb_faces nb_edges nb_vertices
177 // ??? "nb_faces" - all faces or only 'standalone' faces?
178 if (aType == TopAbs_COMPOUND)
181 aKind = SK_COMPSOLID;
183 //theIntegers->Append(anInfo.NbSubShapes(TopAbs_COMPOUND));
184 //theIntegers->Append(anInfo.NbSubShapes(TopAbs_COMPSOLID));
185 theIntegers->Append(anInfo.NbSubShapes(TopAbs_SOLID));
186 theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
187 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
188 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
194 // (+) geompy.kind.SHELL geompy.info.closed nb_faces nb_edges nb_vertices
195 // (+) geompy.kind.SHELL geompy.info.unclosed nb_faces nb_edges nb_vertices
198 theIntegers->Append((int)anInfo.KindOfClosed());
200 theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
201 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
202 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
208 // (+) geompy.kind.WIRE geompy.info.closed nb_edges nb_vertices
209 // (+) geompy.kind.WIRE geompy.info.unclosed nb_edges nb_vertices
212 theIntegers->Append((int)anInfo.KindOfClosed());
214 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
215 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
223 GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
226 case GEOMAlgo_KN_SPHERE:
227 // (+) geompy.kind.SPHERE xc yc zc R
231 gp_Pnt aC = anInfo.Location();
232 theDoubles->Append(aC.X());
233 theDoubles->Append(aC.Y());
234 theDoubles->Append(aC.Z());
236 theDoubles->Append(anInfo.Radius1());
239 case GEOMAlgo_KN_CYLINDER:
240 // (+) geompy.kind.CYLINDER xb yb zb dx dy dz R H
244 gp_Pnt aC = anInfo.Location();
245 theDoubles->Append(aC.X());
246 theDoubles->Append(aC.Y());
247 theDoubles->Append(aC.Z());
249 gp_Ax3 anAx3 = anInfo.Position();
250 gp_Dir aD = anAx3.Direction();
251 theDoubles->Append(aD.X());
252 theDoubles->Append(aD.Y());
253 theDoubles->Append(aD.Z());
255 theDoubles->Append(anInfo.Radius1());
256 theDoubles->Append(anInfo.Height());
259 case GEOMAlgo_KN_BOX:
260 // (+) geompy.kind.BOX xc yc zc ax ay az
264 gp_Pnt aC = anInfo.Location();
265 theDoubles->Append(aC.X());
266 theDoubles->Append(aC.Y());
267 theDoubles->Append(aC.Z());
269 gp_Ax3 anAx3 = anInfo.Position();
270 gp_Dir aD = anAx3.Direction();
271 gp_Dir aX = anAx3.XDirection();
274 if (aD.IsParallel(gp::DZ(), Precision::Angular()) &&
275 aX.IsParallel(gp::DX(), Precision::Angular())) {
276 theDoubles->Append(anInfo.Length()); // ax'
277 theDoubles->Append(anInfo.Width()); // ay'
278 theDoubles->Append(anInfo.Height()); // az'
280 else if (aD.IsParallel(gp::DZ(), Precision::Angular()) &&
281 aX.IsParallel(gp::DY(), Precision::Angular())) {
282 theDoubles->Append(anInfo.Width()); // ay'
283 theDoubles->Append(anInfo.Length()); // ax'
284 theDoubles->Append(anInfo.Height()); // az'
286 else if (aD.IsParallel(gp::DX(), Precision::Angular()) &&
287 aX.IsParallel(gp::DZ(), Precision::Angular())) {
288 theDoubles->Append(anInfo.Height()); // az'
289 theDoubles->Append(anInfo.Width()); // ay'
290 theDoubles->Append(anInfo.Length()); // ax'
292 else if (aD.IsParallel(gp::DX(), Precision::Angular()) &&
293 aX.IsParallel(gp::DY(), Precision::Angular())) {
294 theDoubles->Append(anInfo.Height()); // az'
295 theDoubles->Append(anInfo.Length()); // ax'
296 theDoubles->Append(anInfo.Width()); // ay'
298 else if (aD.IsParallel(gp::DY(), Precision::Angular()) &&
299 aX.IsParallel(gp::DZ(), Precision::Angular())) {
300 theDoubles->Append(anInfo.Width()); // ay'
301 theDoubles->Append(anInfo.Height()); // az'
302 theDoubles->Append(anInfo.Length()); // ax'
304 else if (aD.IsParallel(gp::DY(), Precision::Angular()) &&
305 aX.IsParallel(gp::DX(), Precision::Angular())) {
306 theDoubles->Append(anInfo.Length()); // ax'
307 theDoubles->Append(anInfo.Height()); // az'
308 theDoubles->Append(anInfo.Width()); // ay'
311 // (+) geompy.kind.ROTATED_BOX xo yo zo zx zy zz xx xy xz ax ay az
312 aKind = SK_ROTATED_BOX;
314 // Direction and XDirection
315 theDoubles->Append(aD.X());
316 theDoubles->Append(aD.Y());
317 theDoubles->Append(aD.Z());
319 theDoubles->Append(aX.X());
320 theDoubles->Append(aX.Y());
321 theDoubles->Append(aX.Z());
324 theDoubles->Append(anInfo.Length());
325 theDoubles->Append(anInfo.Width());
326 theDoubles->Append(anInfo.Height());
330 case GEOMAlgo_KN_TORUS:
331 // (+) geompy.kind.TORUS xc yc zc dx dy dz R_1 R_2
335 gp_Pnt aO = anInfo.Location();
336 theDoubles->Append(aO.X());
337 theDoubles->Append(aO.Y());
338 theDoubles->Append(aO.Z());
340 gp_Ax3 anAx3 = anInfo.Position();
341 gp_Dir aD = anAx3.Direction();
342 theDoubles->Append(aD.X());
343 theDoubles->Append(aD.Y());
344 theDoubles->Append(aD.Z());
346 theDoubles->Append(anInfo.Radius1());
347 theDoubles->Append(anInfo.Radius2());
350 case GEOMAlgo_KN_CONE:
351 // (+) geompy.kind.CONE xb yb zb dx dy dz R_1 R_2 H
355 gp_Pnt aO = anInfo.Location();
356 theDoubles->Append(aO.X());
357 theDoubles->Append(aO.Y());
358 theDoubles->Append(aO.Z());
360 gp_Ax3 anAx3 = anInfo.Position();
361 gp_Dir aD = anAx3.Direction();
362 theDoubles->Append(aD.X());
363 theDoubles->Append(aD.Y());
364 theDoubles->Append(aD.Z());
366 theDoubles->Append(anInfo.Radius1());
367 theDoubles->Append(anInfo.Radius2());
368 theDoubles->Append(anInfo.Height());
371 case GEOMAlgo_KN_POLYHEDRON:
372 // (+) geompy.kind.POLYHEDRON nb_faces nb_edges nb_vertices
374 aKind = SK_POLYHEDRON;
376 theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
377 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
378 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
382 // (+) geompy.kind.SOLID nb_faces nb_edges nb_vertices
384 theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
385 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
386 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
396 GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
398 case GEOMAlgo_KN_SPHERE:
399 // (+) geompy.kind.SPHERE2D xc yc zc R
403 gp_Pnt aC = anInfo.Location();
404 theDoubles->Append(aC.X());
405 theDoubles->Append(aC.Y());
406 theDoubles->Append(aC.Z());
408 theDoubles->Append(anInfo.Radius1());
411 case GEOMAlgo_KN_CYLINDER:
412 // (+) geompy.kind.CYLINDER2D xb yb zb dx dy dz R H
414 aKind = SK_CYLINDER2D;
416 gp_Pnt aO = anInfo.Location();
417 theDoubles->Append(aO.X());
418 theDoubles->Append(aO.Y());
419 theDoubles->Append(aO.Z());
421 gp_Ax3 anAx3 = anInfo.Position();
422 gp_Dir aD = anAx3.Direction();
423 theDoubles->Append(aD.X());
424 theDoubles->Append(aD.Y());
425 theDoubles->Append(aD.Z());
427 theDoubles->Append(anInfo.Radius1());
428 theDoubles->Append(anInfo.Height());
431 case GEOMAlgo_KN_TORUS:
432 // (+) geompy.kind.TORUS2D xc yc zc dx dy dz R_1 R_2
436 gp_Pnt aO = anInfo.Location();
437 theDoubles->Append(aO.X());
438 theDoubles->Append(aO.Y());
439 theDoubles->Append(aO.Z());
441 gp_Ax3 anAx3 = anInfo.Position();
442 gp_Dir aD = anAx3.Direction();
443 theDoubles->Append(aD.X());
444 theDoubles->Append(aD.Y());
445 theDoubles->Append(aD.Z());
447 theDoubles->Append(anInfo.Radius1());
448 theDoubles->Append(anInfo.Radius2());
451 case GEOMAlgo_KN_CONE:
452 // (+) geompy.kind.CONE2D xc yc zc dx dy dz R_1 R_2 H
456 gp_Pnt aO = anInfo.Location();
457 theDoubles->Append(aO.X());
458 theDoubles->Append(aO.Y());
459 theDoubles->Append(aO.Z());
461 gp_Ax3 anAx3 = anInfo.Position();
462 gp_Dir aD = anAx3.Direction();
463 theDoubles->Append(aD.X());
464 theDoubles->Append(aD.Y());
465 theDoubles->Append(aD.Z());
467 theDoubles->Append(anInfo.Radius1());
468 theDoubles->Append(anInfo.Radius2());
469 theDoubles->Append(anInfo.Height());
472 case GEOMAlgo_KN_DISKCIRCLE:
473 // (+) geompy.kind.DISK_CIRCLE xc yc zc dx dy dz R
475 aKind = SK_DISK_CIRCLE;
477 gp_Pnt aC = anInfo.Location();
478 theDoubles->Append(aC.X());
479 theDoubles->Append(aC.Y());
480 theDoubles->Append(aC.Z());
482 gp_Ax3 anAx3 = anInfo.Position();
483 gp_Dir aD = anAx3.Direction();
484 theDoubles->Append(aD.X());
485 theDoubles->Append(aD.Y());
486 theDoubles->Append(aD.Z());
488 theDoubles->Append(anInfo.Radius1());
491 case GEOMAlgo_KN_DISKELLIPSE:
492 // (+) geompy.kind.DISK_ELLIPSE xc yc zc dx dy dz R_1 R_2
494 aKind = SK_DISK_ELLIPSE;
496 gp_Pnt aC = anInfo.Location();
497 theDoubles->Append(aC.X());
498 theDoubles->Append(aC.Y());
499 theDoubles->Append(aC.Z());
501 gp_Ax3 anAx3 = anInfo.Position();
502 gp_Dir aD = anAx3.Direction();
503 theDoubles->Append(aD.X());
504 theDoubles->Append(aD.Y());
505 theDoubles->Append(aD.Z());
507 theDoubles->Append(anInfo.Radius1());
508 theDoubles->Append(anInfo.Radius2());
511 case GEOMAlgo_KN_RECTANGLE:
512 case GEOMAlgo_KN_TRIANGLE:
513 case GEOMAlgo_KN_QUADRANGLE:
514 case GEOMAlgo_KN_POLYGON:
515 // (+) geompy.kind.POLYGON xo yo zo dx dy dz nb_edges nb_vertices
519 gp_Pnt aO = anInfo.Location();
520 theDoubles->Append(aO.X());
521 theDoubles->Append(aO.Y());
522 theDoubles->Append(aO.Z());
524 gp_Ax3 anAx3 = anInfo.Position();
525 gp_Dir aD = anAx3.Direction();
526 theDoubles->Append(aD.X());
527 theDoubles->Append(aD.Y());
528 theDoubles->Append(aD.Z());
530 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
531 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
534 case GEOMAlgo_KN_PLANE: // infinite
535 // (+) geompy.kind.PLANE xo yo zo dx dy dz
539 gp_Pnt aC = anInfo.Location();
540 theDoubles->Append(aC.X());
541 theDoubles->Append(aC.Y());
542 theDoubles->Append(aC.Z());
544 gp_Ax3 anAx3 = anInfo.Position();
545 gp_Dir aD = anAx3.Direction();
546 theDoubles->Append(aD.X());
547 theDoubles->Append(aD.Y());
548 theDoubles->Append(aD.Z());
552 if (anInfo.KindOfShape() == GEOMAlgo_KS_PLANE) {
553 // (+) geompy.kind.PLANAR xo yo zo dx dy dz nb_edges nb_vertices
557 gp_Pnt aC = anInfo.Location();
558 theDoubles->Append(aC.X());
559 theDoubles->Append(aC.Y());
560 theDoubles->Append(aC.Z());
562 gp_Ax3 anAx3 = anInfo.Position();
563 gp_Dir aD = anAx3.Direction();
564 theDoubles->Append(aD.X());
565 theDoubles->Append(aD.Y());
566 theDoubles->Append(aD.Z());
568 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
569 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
572 // ??? geompy.kind.FACE nb_edges nb_vertices _surface_type_id_
573 // (+) geompy.kind.FACE nb_edges nb_vertices
575 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
576 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
586 GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
588 case GEOMAlgo_KN_CIRCLE:
590 // (+) geompy.kind.CIRCLE xc yc zc dx dy dz R
593 gp_Pnt aC = anInfo.Location();
594 theDoubles->Append(aC.X());
595 theDoubles->Append(aC.Y());
596 theDoubles->Append(aC.Z());
598 gp_Ax3 anAx3 = anInfo.Position();
599 gp_Dir aD = anAx3.Direction();
600 theDoubles->Append(aD.X());
601 theDoubles->Append(aD.Y());
602 theDoubles->Append(aD.Z());
604 theDoubles->Append(anInfo.Radius1());
607 case GEOMAlgo_KN_ARCCIRCLE:
609 // (+) geompy.kind.ARC_CIRCLE xc yc zc dx dy dz R x1 y1 z1 x2 y2 z2
610 aKind = SK_ARC_CIRCLE;
612 gp_Pnt aC = anInfo.Location();
613 theDoubles->Append(aC.X());
614 theDoubles->Append(aC.Y());
615 theDoubles->Append(aC.Z());
617 gp_Ax3 anAx3 = anInfo.Position();
618 gp_Dir aD = anAx3.Direction();
619 theDoubles->Append(aD.X());
620 theDoubles->Append(aD.Y());
621 theDoubles->Append(aD.Z());
623 theDoubles->Append(anInfo.Radius1());
625 gp_Pnt aP1 = anInfo.Pnt1();
626 theDoubles->Append(aP1.X());
627 theDoubles->Append(aP1.Y());
628 theDoubles->Append(aP1.Z());
630 gp_Pnt aP2 = anInfo.Pnt2();
631 theDoubles->Append(aP2.X());
632 theDoubles->Append(aP2.Y());
633 theDoubles->Append(aP2.Z());
636 case GEOMAlgo_KN_ELLIPSE:
638 // (+) geompy.kind.ELLIPSE xc yc zc dx dy dz R_1 R_2
641 gp_Pnt aC = anInfo.Location();
642 theDoubles->Append(aC.X());
643 theDoubles->Append(aC.Y());
644 theDoubles->Append(aC.Z());
646 gp_Ax3 anAx3 = anInfo.Position();
647 gp_Dir aD = anAx3.Direction();
648 theDoubles->Append(aD.X());
649 theDoubles->Append(aD.Y());
650 theDoubles->Append(aD.Z());
652 theDoubles->Append(anInfo.Radius1());
653 theDoubles->Append(anInfo.Radius2());
656 case GEOMAlgo_KN_ARCELLIPSE:
658 // (+) geompy.kind.ARC_ELLIPSE xc yc zc dx dy dz R_1 R_2 x1 y1 z1 x2 y2 z2
659 aKind = SK_ARC_ELLIPSE;
661 gp_Pnt aC = anInfo.Location();
662 theDoubles->Append(aC.X());
663 theDoubles->Append(aC.Y());
664 theDoubles->Append(aC.Z());
666 gp_Ax3 anAx3 = anInfo.Position();
667 gp_Dir aD = anAx3.Direction();
668 theDoubles->Append(aD.X());
669 theDoubles->Append(aD.Y());
670 theDoubles->Append(aD.Z());
672 theDoubles->Append(anInfo.Radius1());
673 theDoubles->Append(anInfo.Radius2());
675 gp_Pnt aP1 = anInfo.Pnt1();
676 theDoubles->Append(aP1.X());
677 theDoubles->Append(aP1.Y());
678 theDoubles->Append(aP1.Z());
680 gp_Pnt aP2 = anInfo.Pnt2();
681 theDoubles->Append(aP2.X());
682 theDoubles->Append(aP2.Y());
683 theDoubles->Append(aP2.Z());
686 case GEOMAlgo_KN_LINE:
688 // ??? geompy.kind.LINE x1 y1 z1 x2 y2 z2
689 // (+) geompy.kind.LINE x1 y1 z1 dx dy dz
692 gp_Pnt aO = anInfo.Location();
693 theDoubles->Append(aO.X());
694 theDoubles->Append(aO.Y());
695 theDoubles->Append(aO.Z());
697 gp_Dir aD = anInfo.Direction();
698 theDoubles->Append(aD.X());
699 theDoubles->Append(aD.Y());
700 theDoubles->Append(aD.Z());
703 case GEOMAlgo_KN_SEGMENT:
705 // (+) geompy.kind.SEGMENT x1 y1 z1 x2 y2 z2
708 gp_Pnt aP1 = anInfo.Pnt1();
709 theDoubles->Append(aP1.X());
710 theDoubles->Append(aP1.Y());
711 theDoubles->Append(aP1.Z());
713 gp_Pnt aP2 = anInfo.Pnt2();
714 theDoubles->Append(aP2.X());
715 theDoubles->Append(aP2.Y());
716 theDoubles->Append(aP2.Z());
720 // ??? geompy.kind.EDGE nb_vertices _curve_type_id_
721 // (+) geompy.kind.EDGE nb_vertices
722 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
729 // (+) geompy.kind.VERTEX x y z
732 gp_Pnt aP = anInfo.Location();
733 theDoubles->Append(aP.X());
734 theDoubles->Append(aP.Y());
735 theDoubles->Append(aP.Z());
744 //=============================================================================
745 /*! Get LCS, corresponding to the given shape.
746 * Origin of the LCS is situated at the shape's center of mass.
747 * Axes of the LCS are obtained from shape's location or,
748 * if the shape is a planar face, from position of its plane.
750 //=============================================================================
751 gp_Ax3 GEOMImpl_IMeasureOperations::GetPosition (const TopoDS_Shape& theShape)
755 if (theShape.IsNull())
759 aResult.Transform(theShape.Location().Transformation());
760 if (theShape.ShapeType() == TopAbs_FACE) {
761 Handle(Geom_Surface) aGS = BRep_Tool::Surface(TopoDS::Face(theShape));
762 if (!aGS.IsNull() && aGS->IsKind(STANDARD_TYPE(Geom_Plane))) {
763 Handle(Geom_Plane) aGPlane = Handle(Geom_Plane)::DownCast(aGS);
764 gp_Pln aPln = aGPlane->Pln();
765 aResult = aPln.Position();
771 if (theShape.ShapeType() == TopAbs_VERTEX) {
772 aPnt = BRep_Tool::Pnt(TopoDS::Vertex(theShape));
775 GProp_GProps aSystem;
776 if (theShape.ShapeType() == TopAbs_EDGE || theShape.ShapeType() == TopAbs_WIRE)
777 BRepGProp::LinearProperties(theShape, aSystem);
778 else if (theShape.ShapeType() == TopAbs_FACE || theShape.ShapeType() == TopAbs_SHELL)
779 BRepGProp::SurfaceProperties(theShape, aSystem);
781 BRepGProp::VolumeProperties(theShape, aSystem);
783 aPnt = aSystem.CentreOfMass();
786 aResult.SetLocation(aPnt);
791 //=============================================================================
795 //=============================================================================
796 void GEOMImpl_IMeasureOperations::GetPosition
797 (Handle(GEOM_Object) theShape,
798 Standard_Real& Ox, Standard_Real& Oy, Standard_Real& Oz,
799 Standard_Real& Zx, Standard_Real& Zy, Standard_Real& Zz,
800 Standard_Real& Xx, Standard_Real& Xy, Standard_Real& Xz)
804 //Set default values: global CS
805 Ox = Oy = Oz = Zx = Zy = Xy = Xz = 0.;
808 if (theShape.IsNull()) return;
810 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
811 if (aRefShape.IsNull()) return;
813 TopoDS_Shape aShape = aRefShape->GetValue();
814 if (aShape.IsNull()) {
815 SetErrorCode("The Objects has NULL Shape");
820 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
824 gp_Ax3 anAx3 = GetPosition(aShape);
826 gp_Pnt anOri = anAx3.Location();
827 gp_Dir aDirZ = anAx3.Direction();
828 gp_Dir aDirX = anAx3.XDirection();
831 anOri.Coord(Ox, Oy, Oz);
832 aDirZ.Coord(Zx, Zy, Zz);
833 aDirX.Coord(Xx, Xy, Xz);
835 catch (Standard_Failure) {
836 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
837 SetErrorCode(aFail->GetMessageString());
844 //=============================================================================
848 //=============================================================================
849 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetCentreOfMass
850 (Handle(GEOM_Object) theShape)
854 if (theShape.IsNull()) return NULL;
856 //Add a new CentreOfMass object
857 Handle(GEOM_Object) aCDG = GetEngine()->AddObject(GetDocID(), GEOM_CDG);
859 //Add a new CentreOfMass function
860 Handle(GEOM_Function) aFunction =
861 aCDG->AddFunction(GEOMImpl_MeasureDriver::GetID(), CDG_MEASURE);
862 if (aFunction.IsNull()) return NULL;
864 //Check if the function is set correctly
865 if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
867 GEOMImpl_IMeasure aCI (aFunction);
869 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
870 if (aRefShape.IsNull()) return NULL;
872 aCI.SetBase(aRefShape);
874 //Compute the CentreOfMass value
876 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
879 if (!GetSolver()->ComputeFunction(aFunction)) {
880 SetErrorCode("Measure driver failed to compute centre of mass");
884 catch (Standard_Failure) {
885 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
886 SetErrorCode(aFail->GetMessageString());
890 //Make a Python command
891 GEOM::TPythonDump(aFunction) << aCDG << " = geompy.MakeCDG(" << theShape << ")";
897 //=============================================================================
901 //=============================================================================
902 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetNormal
903 (Handle(GEOM_Object) theFace,
904 Handle(GEOM_Object) theOptionalPoint)
908 if (theFace.IsNull()) return NULL;
910 //Add a new Normale object
911 Handle(GEOM_Object) aNorm = GetEngine()->AddObject(GetDocID(), GEOM_VECTOR);
913 //Add a new Normale function
914 Handle(GEOM_Function) aFunction =
915 aNorm->AddFunction(GEOMImpl_MeasureDriver::GetID(), VECTOR_FACE_NORMALE);
916 if (aFunction.IsNull()) return NULL;
918 //Check if the function is set correctly
919 if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
921 GEOMImpl_IMeasure aCI (aFunction);
923 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
924 if (aFace.IsNull()) return NULL;
928 if (!theOptionalPoint.IsNull()) {
929 Handle(GEOM_Function) anOptPnt = theOptionalPoint->GetLastFunction();
930 aCI.SetPoint(anOptPnt);
933 //Compute the Normale value
935 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
938 if (!GetSolver()->ComputeFunction(aFunction)) {
939 SetErrorCode("Measure driver failed to compute normake of face");
943 catch (Standard_Failure) {
944 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
945 SetErrorCode(aFail->GetMessageString());
949 //Make a Python command
950 GEOM::TPythonDump pd (aFunction);
951 pd << aNorm << " = geompy.GetNormal(" << theFace;
952 if (!theOptionalPoint.IsNull()) {
953 pd << ", " << theOptionalPoint;
961 //=============================================================================
965 //=============================================================================
966 void GEOMImpl_IMeasureOperations::GetBasicProperties (Handle(GEOM_Object) theShape,
967 Standard_Real& theLength,
968 Standard_Real& theSurfArea,
969 Standard_Real& theVolume)
973 if (theShape.IsNull()) return;
975 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
976 if (aRefShape.IsNull()) return;
978 TopoDS_Shape aShape = aRefShape->GetValue();
979 if (aShape.IsNull()) {
980 SetErrorCode("The Objects has NULL Shape");
984 //Compute the parameters
985 GProp_GProps LProps, SProps;
987 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
990 BRepGProp::LinearProperties(aShape, LProps);
991 theLength = LProps.Mass();
993 BRepGProp::SurfaceProperties(aShape, SProps);
994 theSurfArea = SProps.Mass();
997 if (aShape.ShapeType() < TopAbs_SHELL) {
998 for (TopExp_Explorer Exp (aShape, TopAbs_SOLID); Exp.More(); Exp.Next()) {
1000 BRepGProp::VolumeProperties(Exp.Current(), VProps);
1001 theVolume += VProps.Mass();
1005 catch (Standard_Failure) {
1006 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1007 SetErrorCode(aFail->GetMessageString());
1014 //=============================================================================
1018 //=============================================================================
1019 void GEOMImpl_IMeasureOperations::GetInertia
1020 (Handle(GEOM_Object) theShape,
1021 Standard_Real& I11, Standard_Real& I12, Standard_Real& I13,
1022 Standard_Real& I21, Standard_Real& I22, Standard_Real& I23,
1023 Standard_Real& I31, Standard_Real& I32, Standard_Real& I33,
1024 Standard_Real& Ix , Standard_Real& Iy , Standard_Real& Iz)
1028 if (theShape.IsNull()) return;
1030 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1031 if (aRefShape.IsNull()) return;
1033 TopoDS_Shape aShape = aRefShape->GetValue();
1034 if (aShape.IsNull()) {
1035 SetErrorCode("The Objects has NULL Shape");
1039 //Compute the parameters
1040 GProp_GProps System;
1043 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1046 if (aShape.ShapeType() == TopAbs_VERTEX ||
1047 aShape.ShapeType() == TopAbs_EDGE ||
1048 aShape.ShapeType() == TopAbs_WIRE) {
1049 BRepGProp::LinearProperties(aShape, System);
1050 } else if (aShape.ShapeType() == TopAbs_FACE ||
1051 aShape.ShapeType() == TopAbs_SHELL) {
1052 BRepGProp::SurfaceProperties(aShape, System);
1054 BRepGProp::VolumeProperties(aShape, System);
1056 gp_Mat I = System.MatrixOfInertia();
1070 GProp_PrincipalProps Pr = System.PrincipalProperties();
1071 Pr.Moments(Ix,Iy,Iz);
1073 catch (Standard_Failure) {
1074 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1075 SetErrorCode(aFail->GetMessageString());
1082 //=============================================================================
1086 //=============================================================================
1087 void GEOMImpl_IMeasureOperations::GetBoundingBox
1088 (Handle(GEOM_Object) theShape,
1089 Standard_Real& Xmin, Standard_Real& Xmax,
1090 Standard_Real& Ymin, Standard_Real& Ymax,
1091 Standard_Real& Zmin, Standard_Real& Zmax)
1095 if (theShape.IsNull()) return;
1097 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1098 if (aRefShape.IsNull()) return;
1100 TopoDS_Shape aShape = aRefShape->GetValue();
1101 if (aShape.IsNull()) {
1102 SetErrorCode("The Objects has NULL Shape");
1106 //Compute the parameters
1110 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1113 BRepBndLib::Add(aShape, B);
1114 B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
1116 catch (Standard_Failure) {
1117 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1118 SetErrorCode(aFail->GetMessageString());
1125 //=============================================================================
1129 //=============================================================================
1130 void GEOMImpl_IMeasureOperations::GetTolerance
1131 (Handle(GEOM_Object) theShape,
1132 Standard_Real& FaceMin, Standard_Real& FaceMax,
1133 Standard_Real& EdgeMin, Standard_Real& EdgeMax,
1134 Standard_Real& VertMin, Standard_Real& VertMax)
1138 if (theShape.IsNull()) return;
1140 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1141 if (aRefShape.IsNull()) return;
1143 TopoDS_Shape aShape = aRefShape->GetValue();
1144 if (aShape.IsNull()) {
1145 SetErrorCode("The Objects has NULL Shape");
1149 //Compute the parameters
1151 FaceMin = EdgeMin = VertMin = RealLast();
1152 FaceMax = EdgeMax = VertMax = -RealLast();
1155 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1158 for (TopExp_Explorer ExF (aShape, TopAbs_FACE); ExF.More(); ExF.Next()) {
1159 TopoDS_Face Face = TopoDS::Face(ExF.Current());
1160 T = BRep_Tool::Tolerance(Face);
1166 for (TopExp_Explorer ExE (aShape, TopAbs_EDGE); ExE.More(); ExE.Next()) {
1167 TopoDS_Edge Edge = TopoDS::Edge(ExE.Current());
1168 T = BRep_Tool::Tolerance(Edge);
1174 for (TopExp_Explorer ExV (aShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1175 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
1176 T = BRep_Tool::Tolerance(Vertex);
1183 catch (Standard_Failure) {
1184 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1185 SetErrorCode(aFail->GetMessageString());
1192 //=============================================================================
1196 //=============================================================================
1197 bool GEOMImpl_IMeasureOperations::CheckShape (Handle(GEOM_Object) theShape,
1198 const Standard_Boolean theIsCheckGeom,
1199 TCollection_AsciiString& theDump)
1203 if (theShape.IsNull()) return false;
1205 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1206 if (aRefShape.IsNull()) return false;
1208 TopoDS_Shape aShape = aRefShape->GetValue();
1209 if (aShape.IsNull()) {
1210 SetErrorCode("The Objects has NULL Shape");
1214 //Compute the parameters
1215 bool isValid = false;
1217 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1220 BRepCheck_Analyzer ana (aShape, theIsCheckGeom);
1221 if (ana.IsValid()) {
1225 StructuralDump(ana, aShape, theDump);
1228 catch (Standard_Failure) {
1229 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1230 SetErrorCode(aFail->GetMessageString());
1238 //=============================================================================
1242 //=============================================================================
1243 TCollection_AsciiString GEOMImpl_IMeasureOperations::WhatIs (Handle(GEOM_Object) theShape)
1247 TCollection_AsciiString Astr;
1249 if (theShape.IsNull()) return Astr;
1251 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1252 if (aRefShape.IsNull()) return Astr;
1254 TopoDS_Shape aShape = aRefShape->GetValue();
1255 if (aShape.IsNull()) {
1256 SetErrorCode("The Objects has NULL Shape");
1260 //Compute the parameters
1261 if (aShape.ShapeType() == TopAbs_EDGE) {
1262 if (BRep_Tool::Degenerated(TopoDS::Edge(aShape))) {
1263 Astr = Astr + " It is a degenerated edge \n";
1267 Astr = Astr + " Number of sub-shapes : \n";
1270 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1273 int iType, nbTypes [TopAbs_SHAPE];
1274 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1276 nbTypes[aShape.ShapeType()]++;
1278 TopTools_MapOfShape aMapOfShape;
1279 aMapOfShape.Add(aShape);
1280 TopTools_ListOfShape aListOfShape;
1281 aListOfShape.Append(aShape);
1283 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1284 for (; itL.More(); itL.Next()) {
1285 TopoDS_Iterator it (itL.Value());
1286 for (; it.More(); it.Next()) {
1287 TopoDS_Shape s = it.Value();
1288 if (aMapOfShape.Add(s)) {
1289 aListOfShape.Append(s);
1290 nbTypes[s.ShapeType()]++;
1295 Astr = Astr + " VERTEX : " + TCollection_AsciiString(nbTypes[TopAbs_VERTEX]) + "\n";
1296 Astr = Astr + " EDGE : " + TCollection_AsciiString(nbTypes[TopAbs_EDGE]) + "\n";
1297 Astr = Astr + " WIRE : " + TCollection_AsciiString(nbTypes[TopAbs_WIRE]) + "\n";
1298 Astr = Astr + " FACE : " + TCollection_AsciiString(nbTypes[TopAbs_FACE]) + "\n";
1299 Astr = Astr + " SHELL : " + TCollection_AsciiString(nbTypes[TopAbs_SHELL]) + "\n";
1300 Astr = Astr + " SOLID : " + TCollection_AsciiString(nbTypes[TopAbs_SOLID]) + "\n";
1301 Astr = Astr + " COMPSOLID : " + TCollection_AsciiString(nbTypes[TopAbs_COMPSOLID]) + "\n";
1302 Astr = Astr + " COMPOUND : " + TCollection_AsciiString(nbTypes[TopAbs_COMPOUND]) + "\n";
1303 Astr = Astr + " SHAPE : " + TCollection_AsciiString(aMapOfShape.Extent());
1305 catch (Standard_Failure) {
1306 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1307 SetErrorCode(aFail->GetMessageString());
1316 //=======================================================================
1317 //function : CheckSingularCase
1318 //purpose : auxilary for GetMinDistance()
1319 // workaround for bugs 19899, 19908 and 19910 from Mantis
1320 //=======================================================================
1321 static double CheckSingularCase(const TopoDS_Shape& aSh1,
1322 const TopoDS_Shape& aSh2,
1323 gp_Pnt& Ptmp1, gp_Pnt& Ptmp2)
1325 bool IsChange1 = false;
1326 double AddDist1 = 0.0;
1327 TopExp_Explorer anExp;
1328 TopoDS_Shape tmpSh1, tmpSh2;
1330 for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
1332 tmpSh1 = anExp.Current();
1335 TopoDS_Shape sh = aSh1;
1336 while(sh.ShapeType()==TopAbs_COMPOUND) {
1337 TopoDS_Iterator it(sh);
1340 Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
1341 if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
1342 S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
1343 if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
1346 S->Bounds(U1,U2,V1,V2);
1347 Handle(Geom_RectangularTrimmedSurface) TrS1 =
1348 new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
1349 Handle(Geom_RectangularTrimmedSurface) TrS2 =
1350 new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
1353 TopoDS_Compound Comp;
1354 B.MakeCompound(Comp);
1355 B.MakeFace(F1,TrS1,1.e-7);
1357 B.MakeFace(F2,TrS2,1.e-7);
1359 Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
1361 sfs->SetPrecision(1.e-6);
1362 sfs->SetMaxTolerance(1.0);
1364 tmpSh1 = sfs->Shape();
1368 if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
1369 Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
1370 gp_Pnt PC = SS->Location();
1373 B.MakeVertex(V,PC,1.e-7);
1375 AddDist1 = SS->Radius();
1379 Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
1380 gp_Ax3 ax3 = TS->Position();
1381 Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
1384 B.MakeEdge(E,C,1.e-7);
1386 AddDist1 = TS->MinorRadius();
1396 bool IsChange2 = false;
1397 double AddDist2 = 0.0;
1399 for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
1401 tmpSh2 = anExp.Current();
1404 TopoDS_Shape sh = aSh2;
1405 while(sh.ShapeType()==TopAbs_COMPOUND) {
1406 TopoDS_Iterator it(sh);
1409 Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
1410 if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
1411 S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
1412 if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
1415 S->Bounds(U1,U2,V1,V2);
1416 Handle(Geom_RectangularTrimmedSurface) TrS1 =
1417 new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
1418 Handle(Geom_RectangularTrimmedSurface) TrS2 =
1419 new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
1422 TopoDS_Compound Comp;
1423 B.MakeCompound(Comp);
1424 B.MakeFace(F1,TrS1,1.e-7);
1426 B.MakeFace(F2,TrS2,1.e-7);
1428 Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
1430 sfs->SetPrecision(1.e-6);
1431 sfs->SetMaxTolerance(1.0);
1433 tmpSh2 = sfs->Shape();
1437 if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
1438 Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
1439 gp_Pnt PC = SS->Location();
1442 B.MakeVertex(V,PC,1.e-7);
1444 AddDist2 = SS->Radius();
1447 else if( S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
1448 Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
1449 gp_Ax3 ax3 = TS->Position();
1450 Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
1453 B.MakeEdge(E,C,1.e-7);
1455 AddDist2 = TS->MinorRadius();
1466 if( !IsChange1 && !IsChange2 )
1469 BRepExtrema_DistShapeShape dst(tmpSh1,tmpSh2);
1471 double MinDist = 1.e9;
1472 gp_Pnt PMin1, PMin2, P1, P2;
1473 for (int i = 1; i <= dst.NbSolution(); i++) {
1474 P1 = dst.PointOnShape1(i);
1475 P2 = dst.PointOnShape2(i);
1476 Standard_Real Dist = P1.Distance(P2);
1477 if (MinDist > Dist) {
1488 gp_Dir aDir(gp_Vec(PMin1,PMin2));
1489 if( MinDist > (AddDist1+AddDist2) ) {
1490 Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
1491 PMin1.Y() + aDir.Y()*AddDist1,
1492 PMin1.Z() + aDir.Z()*AddDist1 );
1493 Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
1494 PMin2.Y() - aDir.Y()*AddDist2,
1495 PMin2.Z() - aDir.Z()*AddDist2 );
1496 return (MinDist - AddDist1 - AddDist2);
1499 if( AddDist1 > 0 ) {
1500 Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
1501 PMin1.Y() + aDir.Y()*AddDist1,
1502 PMin1.Z() + aDir.Z()*AddDist1 );
1506 Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
1507 PMin2.Y() - aDir.Y()*AddDist2,
1508 PMin2.Z() - aDir.Z()*AddDist2 );
1513 double res = MinDist - AddDist1 - AddDist2;
1514 if(res<0.) res = 0.0;
1520 static bool CheckSingularCase(const TopoDS_Shape& aSh1,
1521 const TopoDS_Shape& aSh2,
1524 TopExp_Explorer anExp;
1525 TopoDS_Shape tmpSh1, tmpSh2;
1527 for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
1529 tmpSh1 = anExp.Current();
1532 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
1533 if( S1->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
1534 S1->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
1536 for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
1538 tmpSh2 = anExp.Current();
1539 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
1540 GeomAPI_IntSS ISS(S1,S2,1.e-7);
1542 for(int i=1; i<=ISS.NbLines(); i++) {
1543 Handle(Geom_Curve) C3d = ISS.Line(i);
1546 B.MakeEdge(E,C3d,1.e-7);
1547 BRepExtrema_DistShapeShape dst(tmpSh2,E);
1549 gp_Pnt PMin1, PMin2, P1, P2;
1550 double MinDist = 1.e9;
1551 for (int i = 1; i <= dst.NbSolution(); i++) {
1552 P1 = dst.PointOnShape1(i);
1553 P2 = dst.PointOnShape2(i);
1554 Standard_Real Dist = P1.Distance(P2);
1555 if (MinDist > Dist) {
1569 for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
1571 tmpSh1 = anExp.Current();
1574 Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
1575 if( S1->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
1576 S1->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
1578 for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
1580 tmpSh2 = anExp.Current();
1581 Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
1582 GeomAPI_IntSS ISS(S1,S2,1.e-7);
1584 for(int i=1; i<=ISS.NbLines(); i++) {
1585 Handle(Geom_Curve) C3d = ISS.Line(i);
1588 B.MakeEdge(E,C3d,1.e-7);
1589 BRepExtrema_DistShapeShape dst(tmpSh2,E);
1592 double MinDist = 1.e9;
1593 for (int i = 1; i <= dst.NbSolution(); i++) {
1594 P1 = dst.PointOnShape1(i);
1595 P2 = dst.PointOnShape2(i);
1596 Standard_Real Dist = P1.Distance(P2);
1597 if (MinDist > Dist) {
1615 //=============================================================================
1619 //=============================================================================
1620 Standard_Real GEOMImpl_IMeasureOperations::GetMinDistance
1621 (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2,
1622 Standard_Real& X1, Standard_Real& Y1, Standard_Real& Z1,
1623 Standard_Real& X2, Standard_Real& Y2, Standard_Real& Z2)
1626 Standard_Real MinDist = 1.e9;
1628 if (theShape1.IsNull() || theShape2.IsNull()) return MinDist;
1630 Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction();
1631 Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction();
1632 if (aRefShape1.IsNull() || aRefShape2.IsNull()) return MinDist;
1634 TopoDS_Shape aShape1 = aRefShape1->GetValue();
1635 TopoDS_Shape aShape2 = aRefShape2->GetValue();
1636 if (aShape1.IsNull() || aShape2.IsNull()) {
1637 SetErrorCode("One of Objects has NULL Shape");
1641 //Compute the parameters
1643 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1648 // additional workaround for bugs 19899, 19908 and 19910 from Mantis
1649 gp_Pnt Ptmp1, Ptmp2;
1650 double dist = CheckSingularCase(aShape1, aShape2, Ptmp1, Ptmp2);
1652 Ptmp1.Coord(X1, Y1, Z1);
1653 Ptmp2.Coord(X2, Y2, Z2);
1658 BRepExtrema_DistShapeShape dst (aShape1, aShape2);
1660 gp_Pnt PMin1, PMin2, P1, P2;
1662 for (int i = 1; i <= dst.NbSolution(); i++) {
1663 P1 = dst.PointOnShape1(i);
1664 P2 = dst.PointOnShape2(i);
1666 Standard_Real Dist = P1.Distance(P2);
1667 if (MinDist > Dist) {
1674 PMin1.Coord(X1, Y1, Z1);
1675 PMin2.Coord(X2, Y2, Z2);
1678 catch (Standard_Failure) {
1679 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1680 SetErrorCode(aFail->GetMessageString());
1688 //=======================================================================
1690 * Get coordinates of point
1692 //=======================================================================
1693 void GEOMImpl_IMeasureOperations::PointCoordinates (Handle(GEOM_Object) theShape,
1694 Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ)
1698 if (theShape.IsNull())
1701 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1702 if (aRefShape.IsNull())
1705 TopoDS_Shape aShape = aRefShape->GetValue();
1706 if (aShape.IsNull() || aShape.ShapeType() != TopAbs_VERTEX)
1708 SetErrorCode( "Shape must be a vertex" );
1713 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1716 gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
1723 catch (Standard_Failure)
1725 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1726 SetErrorCode( aFail->GetMessageString() );
1730 //=======================================================================
1732 * Compute angle (in degrees) between two lines
1734 //=======================================================================
1735 Standard_Real GEOMImpl_IMeasureOperations::GetAngle (Handle(GEOM_Object) theLine1,
1736 Handle(GEOM_Object) theLine2)
1740 Standard_Real anAngle = -1.0;
1742 if (theLine1.IsNull() || theLine2.IsNull())
1745 Handle(GEOM_Function) aRefLine1 = theLine1->GetLastFunction();
1746 Handle(GEOM_Function) aRefLine2 = theLine2->GetLastFunction();
1747 if (aRefLine1.IsNull() || aRefLine2.IsNull())
1750 TopoDS_Shape aLine1 = aRefLine1->GetValue();
1751 TopoDS_Shape aLine2 = aRefLine2->GetValue();
1752 if (aLine1.IsNull() || aLine2.IsNull() ||
1753 aLine1.ShapeType() != TopAbs_EDGE ||
1754 aLine2.ShapeType() != TopAbs_EDGE)
1756 SetErrorCode("Two edges must be given");
1761 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1764 TopoDS_Edge E1 = TopoDS::Edge(aLine1);
1765 TopoDS_Edge E2 = TopoDS::Edge(aLine2);
1768 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
1769 Handle(Geom_Curve) C2 = BRep_Tool::Curve(E2,fp,lp);
1771 if ( C1.IsNull() || C2.IsNull() ||
1772 !C1->IsKind(STANDARD_TYPE(Geom_Line)) ||
1773 !C2->IsKind(STANDARD_TYPE(Geom_Line)))
1775 SetErrorCode("The edges must be linear");
1779 Handle(Geom_Line) L1 = Handle(Geom_Line)::DownCast(C1);
1780 Handle(Geom_Line) L2 = Handle(Geom_Line)::DownCast(C2);
1782 gp_Lin aLin1 = L1->Lin();
1783 gp_Lin aLin2 = L2->Lin();
1785 anAngle = aLin1.Angle(aLin2);
1786 anAngle /= PI180; // convert radians into degrees
1790 catch (Standard_Failure)
1792 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1793 SetErrorCode(aFail->GetMessageString());
1800 //=============================================================================
1802 * CurveCurvatureByParam
1804 //=============================================================================
1805 Standard_Real GEOMImpl_IMeasureOperations::CurveCurvatureByParam
1806 (Handle(GEOM_Object) theCurve, Standard_Real& theParam)
1809 Standard_Real aRes = -1.0;
1811 if(theCurve.IsNull()) return aRes;
1813 Handle(GEOM_Function) aRefShape = theCurve->GetLastFunction();
1814 if(aRefShape.IsNull()) return aRes;
1816 TopoDS_Shape aShape = aRefShape->GetValue();
1817 if(aShape.IsNull()) {
1818 SetErrorCode("One of Objects has NULL Shape");
1822 Standard_Real aFP, aLP, aP;
1823 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aShape), aFP, aLP);
1824 aP = aFP + (aLP - aFP) * theParam;
1826 if(aCurve.IsNull()) return aRes;
1830 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1833 GeomLProp_CLProps Prop = GeomLProp_CLProps
1834 (aCurve, aP, 2, Precision::Confusion());
1835 aRes = fabs(Prop.Curvature());
1838 catch (Standard_Failure) {
1839 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1840 SetErrorCode(aFail->GetMessageString());
1844 if( aRes > Precision::Confusion() )
1853 //=============================================================================
1855 * CurveCurvatureByPoint
1857 //=============================================================================
1858 Standard_Real GEOMImpl_IMeasureOperations::CurveCurvatureByPoint
1859 (Handle(GEOM_Object) theCurve, Handle(GEOM_Object) thePoint)
1862 Standard_Real aRes = -1.0;
1864 if( theCurve.IsNull() || thePoint.IsNull() ) return aRes;
1866 Handle(GEOM_Function) aRefCurve = theCurve->GetLastFunction();
1867 Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction();
1868 if( aRefCurve.IsNull() || aRefPoint.IsNull() ) return aRes;
1870 TopoDS_Edge anEdge = TopoDS::Edge(aRefCurve->GetValue());
1871 TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue());
1872 if( anEdge.IsNull() || aPnt.IsNull() ) {
1873 SetErrorCode("One of Objects has NULL Shape");
1877 Standard_Real aFP, aLP;
1878 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFP, aLP);
1879 if(aCurve.IsNull()) return aRes;
1880 gp_Pnt aPoint = BRep_Tool::Pnt(aPnt);
1884 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1887 GeomAPI_ProjectPointOnCurve PPC(aPoint, aCurve, aFP, aLP);
1888 if(PPC.NbPoints()>0) {
1889 GeomLProp_CLProps Prop = GeomLProp_CLProps
1890 (aCurve, PPC.LowerDistanceParameter(), 2, Precision::Confusion());
1891 aRes = fabs(Prop.Curvature());
1895 catch (Standard_Failure) {
1896 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1897 SetErrorCode(aFail->GetMessageString());
1901 if( aRes > Precision::Confusion() )
1910 //=============================================================================
1912 * getSurfaceCurvatures
1914 //=============================================================================
1915 Standard_Real GEOMImpl_IMeasureOperations::getSurfaceCurvatures
1916 (const Handle(Geom_Surface)& aSurf,
1917 Standard_Real theUParam,
1918 Standard_Real theVParam,
1919 Standard_Boolean theNeedMaxCurv)
1922 Standard_Real aRes = 1.0;
1924 if (aSurf.IsNull()) return aRes;
1927 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1930 GeomLProp_SLProps Prop = GeomLProp_SLProps
1931 (aSurf, theUParam, theVParam, 2, Precision::Confusion());
1932 if(Prop.IsCurvatureDefined()) {
1933 if(Prop.IsUmbilic()) {
1934 //cout<<"is umbilic"<<endl;
1935 aRes = fabs(Prop.MeanCurvature());
1938 //cout<<"is not umbilic"<<endl;
1939 double c1 = fabs(Prop.MaxCurvature());
1940 double c2 = fabs(Prop.MinCurvature());
1949 catch (Standard_Failure) {
1950 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1951 SetErrorCode(aFail->GetMessageString());
1955 if( fabs(aRes) > Precision::Confusion() )
1964 //=============================================================================
1966 * MaxSurfaceCurvatureByParam
1968 //=============================================================================
1969 Standard_Real GEOMImpl_IMeasureOperations::MaxSurfaceCurvatureByParam
1970 (Handle(GEOM_Object) theSurf,
1971 Standard_Real& theUParam,
1972 Standard_Real& theVParam)
1975 Standard_Real aRes = -1.0;
1977 if (theSurf.IsNull()) return aRes;
1979 Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
1980 if(aRefShape.IsNull()) return aRes;
1982 TopoDS_Shape aShape = aRefShape->GetValue();
1983 if(aShape.IsNull()) {
1984 SetErrorCode("One of Objects has NULL Shape");
1988 TopoDS_Face F = TopoDS::Face(aShape);
1989 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
1991 //Compute the parameters
1992 Standard_Real U1,U2,V1,V2;
1993 ShapeAnalysis::GetFaceUVBounds(F,U1,U2,V1,V2);
1994 Standard_Real U = U1 + (U2-U1)*theUParam;
1995 Standard_Real V = V1 + (V2-V1)*theVParam;
1997 return getSurfaceCurvatures(aSurf, U, V, true);
2001 //=============================================================================
2003 * MaxSurfaceCurvatureByPoint
2005 //=============================================================================
2006 Standard_Real GEOMImpl_IMeasureOperations::MaxSurfaceCurvatureByPoint
2007 (Handle(GEOM_Object) theSurf, Handle(GEOM_Object) thePoint)
2010 Standard_Real aRes = -1.0;
2012 if( theSurf.IsNull() || thePoint.IsNull() ) return aRes;
2014 Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
2015 Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction();
2016 if( aRefShape.IsNull() || aRefPoint.IsNull() ) return aRes;
2018 TopoDS_Face aFace = TopoDS::Face(aRefShape->GetValue());
2019 TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue());
2020 if( aFace.IsNull() || aPnt.IsNull() ) {
2021 SetErrorCode("One of Objects has NULL Shape");
2025 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
2026 if(aSurf.IsNull()) return aRes;
2027 gp_Pnt aPoint = BRep_Tool::Pnt(aPnt);
2029 //Compute the parameters
2030 ShapeAnalysis_Surface sas(aSurf);
2031 gp_Pnt2d UV = sas.ValueOfUV(aPoint,Precision::Confusion());
2033 return getSurfaceCurvatures(aSurf, UV.X(), UV.Y(), true);
2037 //=============================================================================
2039 * MinSurfaceCurvatureByParam
2041 //=============================================================================
2042 Standard_Real GEOMImpl_IMeasureOperations::MinSurfaceCurvatureByParam
2043 (Handle(GEOM_Object) theSurf,
2044 Standard_Real& theUParam,
2045 Standard_Real& theVParam)
2048 Standard_Real aRes = -1.0;
2050 if (theSurf.IsNull()) return aRes;
2052 Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
2053 if(aRefShape.IsNull()) return aRes;
2055 TopoDS_Shape aShape = aRefShape->GetValue();
2056 if(aShape.IsNull()) {
2057 SetErrorCode("One of Objects has NULL Shape");
2061 TopoDS_Face F = TopoDS::Face(aShape);
2062 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
2064 //Compute the parameters
2065 Standard_Real U1,U2,V1,V2;
2066 ShapeAnalysis::GetFaceUVBounds(F,U1,U2,V1,V2);
2067 Standard_Real U = U1 + (U2-U1)*theUParam;
2068 Standard_Real V = V1 + (V2-V1)*theVParam;
2070 return getSurfaceCurvatures(aSurf, U, V, false);
2074 //=============================================================================
2076 * MinSurfaceCurvatureByPoint
2078 //=============================================================================
2079 Standard_Real GEOMImpl_IMeasureOperations::MinSurfaceCurvatureByPoint
2080 (Handle(GEOM_Object) theSurf, Handle(GEOM_Object) thePoint)
2083 Standard_Real aRes = -1.0;
2085 if( theSurf.IsNull() || thePoint.IsNull() ) return aRes;
2087 Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
2088 Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction();
2089 if( aRefShape.IsNull() || aRefPoint.IsNull() ) return aRes;
2091 TopoDS_Face aFace = TopoDS::Face(aRefShape->GetValue());
2092 TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue());
2093 if( aFace.IsNull() || aPnt.IsNull() ) {
2094 SetErrorCode("One of Objects has NULL Shape");
2098 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
2099 if(aSurf.IsNull()) return aRes;
2100 gp_Pnt aPoint = BRep_Tool::Pnt(aPnt);
2102 //Compute the parameters
2103 ShapeAnalysis_Surface sas(aSurf);
2104 gp_Pnt2d UV = sas.ValueOfUV(aPoint,Precision::Confusion());
2106 return getSurfaceCurvatures(aSurf, UV.X(), UV.Y(), false);
2110 //=======================================================================
2111 //function : StructuralDump
2112 //purpose : Structural (data exchange) style of output.
2113 //=======================================================================
2114 void GEOMImpl_IMeasureOperations::StructuralDump (const BRepCheck_Analyzer& theAna,
2115 const TopoDS_Shape& theShape,
2116 TCollection_AsciiString& theDump)
2120 theDump += " -- The Shape has problems :\n";
2121 theDump += " Check Count\n";
2122 theDump += " ------------------------------------------------\n";
2124 Standard_Integer last_stat = (Standard_Integer)BRepCheck_CheckFail;
2125 Handle(TColStd_HArray1OfInteger) NbProblems =
2126 new TColStd_HArray1OfInteger(1, last_stat);
2127 for (i = 1; i <= last_stat; i++)
2128 NbProblems->SetValue(i,0);
2130 Handle(TopTools_HSequenceOfShape) sl;
2131 sl = new TopTools_HSequenceOfShape();
2132 TopTools_DataMapOfShapeListOfShape theMap;
2134 GetProblemShapes(theAna, theShape, sl, NbProblems, theMap);
2137 Standard_Integer count = 0;
2138 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnCurve);
2140 theDump += " Invalid Point on Curve ................... ";
2141 theDump += TCollection_AsciiString(count) + "\n";
2143 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnCurveOnSurface);
2145 theDump += " Invalid Point on CurveOnSurface .......... ";
2146 theDump += TCollection_AsciiString(count) + "\n";
2148 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnSurface);
2150 theDump += " Invalid Point on Surface ................. ";
2151 theDump += TCollection_AsciiString(count) + "\n";
2153 count = NbProblems->Value((Standard_Integer)BRepCheck_No3DCurve);
2155 theDump += " No 3D Curve .............................. ";
2156 theDump += TCollection_AsciiString(count) + "\n";
2158 count = NbProblems->Value((Standard_Integer)BRepCheck_Multiple3DCurve);
2160 theDump += " Multiple 3D Curve ........................ ";
2161 theDump += TCollection_AsciiString(count) + "\n";
2163 count = NbProblems->Value((Standard_Integer)BRepCheck_Invalid3DCurve);
2165 theDump += " Invalid 3D Curve ......................... ";
2166 theDump += TCollection_AsciiString(count) + "\n";
2168 count = NbProblems->Value((Standard_Integer)BRepCheck_NoCurveOnSurface);
2170 theDump += " No Curve on Surface ...................... ";
2171 theDump += TCollection_AsciiString(count) + "\n";
2173 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidCurveOnSurface);
2175 theDump += " Invalid Curve on Surface ................. ";
2176 theDump += TCollection_AsciiString(count) + "\n";
2178 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidCurveOnClosedSurface);
2180 theDump += " Invalid Curve on closed Surface .......... ";
2181 theDump += TCollection_AsciiString(count) + "\n";
2183 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidSameRangeFlag);
2185 theDump += " Invalid SameRange Flag ................... ";
2186 theDump += TCollection_AsciiString(count) + "\n";
2188 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidSameParameterFlag);
2190 theDump += " Invalid SameParameter Flag ............... ";
2191 theDump += TCollection_AsciiString(count) + "\n";
2193 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidDegeneratedFlag);
2195 theDump += " Invalid Degenerated Flag ................. ";
2196 theDump += TCollection_AsciiString(count) + "\n";
2198 count = NbProblems->Value((Standard_Integer)BRepCheck_FreeEdge);
2200 theDump += " Free Edge ................................ ";
2201 theDump += TCollection_AsciiString(count) + "\n";
2203 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidMultiConnexity);
2205 theDump += " Invalid MultiConnexity ................... ";
2206 theDump += TCollection_AsciiString(count) + "\n";
2208 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidRange);
2210 theDump += " Invalid Range ............................ ";
2211 theDump += TCollection_AsciiString(count) + "\n";
2213 count = NbProblems->Value((Standard_Integer)BRepCheck_EmptyWire);
2215 theDump += " Empty Wire ............................... ";
2216 theDump += TCollection_AsciiString(count) + "\n";
2218 count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantEdge);
2220 theDump += " Redundant Edge ........................... ";
2221 theDump += TCollection_AsciiString(count) + "\n";
2223 count = NbProblems->Value((Standard_Integer)BRepCheck_SelfIntersectingWire);
2225 theDump += " Self Intersecting Wire ................... ";
2226 theDump += TCollection_AsciiString(count) + "\n";
2228 count = NbProblems->Value((Standard_Integer)BRepCheck_NoSurface);
2230 theDump += " No Surface ............................... ";
2231 theDump += TCollection_AsciiString(count) + "\n";
2233 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidWire);
2235 theDump += " Invalid Wire ............................. ";
2236 theDump += TCollection_AsciiString(count) + "\n";
2238 count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantWire);
2240 theDump += " Redundant Wire ........................... ";
2241 theDump += TCollection_AsciiString(count) + "\n";
2243 count = NbProblems->Value((Standard_Integer)BRepCheck_IntersectingWires);
2245 theDump += " Intersecting Wires ....................... ";
2246 theDump += TCollection_AsciiString(count) + "\n";
2248 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidImbricationOfWires);
2250 theDump += " Invalid Imbrication of Wires ............. ";
2251 theDump += TCollection_AsciiString(count) + "\n";
2253 count = NbProblems->Value((Standard_Integer)BRepCheck_EmptyShell);
2255 theDump += " Empty Shell .............................. ";
2256 theDump += TCollection_AsciiString(count) + "\n";
2258 count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantFace);
2260 theDump += " Redundant Face ........................... ";
2261 theDump += TCollection_AsciiString(count) + "\n";
2263 count = NbProblems->Value((Standard_Integer)BRepCheck_UnorientableShape);
2265 theDump += " Unorientable Shape ....................... ";
2266 theDump += TCollection_AsciiString(count) + "\n";
2268 count = NbProblems->Value((Standard_Integer)BRepCheck_NotClosed);
2270 theDump += " Not Closed ............................... ";
2271 theDump += TCollection_AsciiString(count) + "\n";
2273 count = NbProblems->Value((Standard_Integer)BRepCheck_NotConnected);
2275 theDump += " Not Connected ............................ ";
2276 theDump += TCollection_AsciiString(count) + "\n";
2278 count = NbProblems->Value((Standard_Integer)BRepCheck_SubshapeNotInShape);
2280 theDump += " Subshape not in Shape .................... ";
2281 theDump += TCollection_AsciiString(count) + "\n";
2283 count = NbProblems->Value((Standard_Integer)BRepCheck_BadOrientation);
2285 theDump += " Bad Orientation .......................... ";
2286 theDump += TCollection_AsciiString(count) + "\n";
2288 count = NbProblems->Value((Standard_Integer)BRepCheck_BadOrientationOfSubshape);
2290 theDump += " Bad Orientation of Subshape .............. ";
2291 theDump += TCollection_AsciiString(count) + "\n";
2293 count = NbProblems->Value((Standard_Integer)BRepCheck_CheckFail);
2295 theDump += " checkshape failure ....................... ";
2296 theDump += TCollection_AsciiString(count) + "\n";
2299 theDump += " ------------------------------------------------\n";
2300 theDump += "*** Shapes with problems : ";
2301 theDump += TCollection_AsciiString(sl->Length()) + "\n";
2303 Standard_Integer nbv, nbe, nbw, nbf, nbs, nbo;
2304 nbv = nbe = nbw = nbf = nbs = nbo = 0;
2306 for (i = 1; i <= sl->Length(); i++) {
2307 TopoDS_Shape shi = sl->Value(i);
2308 TopAbs_ShapeEnum sti = shi.ShapeType();
2310 case TopAbs_VERTEX : nbv++; break;
2311 case TopAbs_EDGE : nbe++; break;
2312 case TopAbs_WIRE : nbw++; break;
2313 case TopAbs_FACE : nbf++; break;
2314 case TopAbs_SHELL : nbs++; break;
2315 case TopAbs_SOLID : nbo++; break;
2321 theDump += "VERTEX : ";
2322 if (nbv < 10) theDump += " ";
2323 theDump += TCollection_AsciiString(nbv) + "\n";
2326 theDump += "EDGE : ";
2327 if (nbe < 10) theDump += " ";
2328 theDump += TCollection_AsciiString(nbe) + "\n";
2331 theDump += "WIRE : ";
2332 if (nbw < 10) theDump += " ";
2333 theDump += TCollection_AsciiString(nbw) + "\n";
2336 theDump += "FACE : ";
2337 if (nbf < 10) theDump += " ";
2338 theDump += TCollection_AsciiString(nbf) + "\n";
2341 theDump += "SHELL : ";
2342 if (nbs < 10) theDump += " ";
2343 theDump += TCollection_AsciiString(nbs) + "\n";
2346 theDump += "SOLID : ";
2347 if (nbo < 10) theDump += " ";
2348 theDump += TCollection_AsciiString(nbo) + "\n";
2353 //=======================================================================
2354 //function : GetProblemShapes
2355 // purpose : for StructuralDump
2356 //=======================================================================
2357 void GEOMImpl_IMeasureOperations::GetProblemShapes (const BRepCheck_Analyzer& theAna,
2358 const TopoDS_Shape& theShape,
2359 Handle(TopTools_HSequenceOfShape)& sl,
2360 Handle(TColStd_HArray1OfInteger)& NbProblems,
2361 TopTools_DataMapOfShapeListOfShape& theMap)
2363 for (TopoDS_Iterator iter(theShape); iter.More(); iter.Next()) {
2364 GetProblemShapes(theAna, iter.Value(), sl, NbProblems, theMap);
2366 TopAbs_ShapeEnum styp = theShape.ShapeType();
2367 BRepCheck_ListIteratorOfListOfStatus itl;
2368 TopTools_ListOfShape empty;
2369 if (!theMap.IsBound(theShape)) {
2370 theMap.Bind(theShape,empty);
2372 if (!theAna.Result(theShape).IsNull()) {
2373 itl.Initialize(theAna.Result(theShape)->Status());
2374 // !!! May be, we have to print all the problems, not only the first one ?
2375 if (itl.Value() != BRepCheck_NoError) {
2376 sl->Append(theShape);
2377 BRepCheck_Status stat = itl.Value();
2378 NbProblems->SetValue((Standard_Integer)stat,
2379 NbProblems->Value((Standard_Integer)stat) + 1);
2386 GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_VERTEX, theMap);
2389 GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_WIRE, theMap);
2390 GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_EDGE, theMap);
2391 GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_VERTEX, theMap);
2396 GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_SHELL, theMap);
2403 //=======================================================================
2404 //function : Contains
2405 //=======================================================================
2406 static Standard_Boolean Contains (const TopTools_ListOfShape& L,
2407 const TopoDS_Shape& S)
2409 TopTools_ListIteratorOfListOfShape it;
2410 for (it.Initialize(L); it.More(); it.Next()) {
2411 if (it.Value().IsSame(S)) {
2412 return Standard_True;
2415 return Standard_False;
2418 //=======================================================================
2419 //function : GetProblemSub
2420 // purpose : for StructuralDump
2421 //=======================================================================
2422 void GEOMImpl_IMeasureOperations::GetProblemSub (const BRepCheck_Analyzer& theAna,
2423 const TopoDS_Shape& theShape,
2424 Handle(TopTools_HSequenceOfShape)& sl,
2425 Handle(TColStd_HArray1OfInteger)& NbProblems,
2426 const TopAbs_ShapeEnum Subtype,
2427 TopTools_DataMapOfShapeListOfShape& theMap)
2429 BRepCheck_ListIteratorOfListOfStatus itl;
2430 TopExp_Explorer exp;
2431 for (exp.Init(theShape, Subtype); exp.More(); exp.Next()) {
2432 const TopoDS_Shape& sub = exp.Current();
2434 const Handle(BRepCheck_Result)& res = theAna.Result(sub);
2435 for (res->InitContextIterator();
2436 res->MoreShapeInContext();
2437 res->NextShapeInContext()) {
2438 if (res->ContextualShape().IsSame(theShape) && !Contains(theMap(sub), theShape)) {
2439 theMap(sub).Append(theShape);
2440 itl.Initialize(res->StatusOnShape());
2442 if (itl.Value() != BRepCheck_NoError) {
2443 Standard_Integer ii = 0;
2445 for (ii = 1; ii <= sl->Length(); ii++)
2446 if (sl->Value(ii).IsSame(sub)) break;
2448 if (ii > sl->Length()) {
2450 BRepCheck_Status stat = itl.Value();
2451 NbProblems->SetValue((Standard_Integer)stat,
2452 NbProblems->Value((Standard_Integer)stat) + 1);
2454 for (ii = 1; ii <= sl->Length(); ii++)
2455 if (sl->Value(ii).IsSame(theShape)) break;
2456 if (ii > sl->Length()) {
2457 sl->Append(theShape);
2458 BRepCheck_Status stat = itl.Value();
2459 NbProblems->SetValue((Standard_Integer)stat,
2460 NbProblems->Value((Standard_Integer)stat) + 1);