1 // Copyright (C) 2007-2022 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, or (at your option) any later version.
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 <GEOMImpl_IMeasureOperations.hxx>
24 #include <GEOMImpl_IMeasure.hxx>
25 #include <GEOMImpl_MeasureDriver.hxx>
27 #include <GEOMImpl_IPatchFace.hxx>
28 #include <GEOMImpl_IProximity.hxx>
29 #include <GEOMImpl_PatchFaceDriver.hxx>
30 #include <GEOMImpl_ShapeProximityDriver.hxx>
32 #include <GEOMImpl_Types.hxx>
34 #include <GEOMImpl_IConformity.hxx>
35 #include <GEOMImpl_ConformityDriver.hxx>
37 #include <GEOMUtils.hxx>
39 #include <GEOMAlgo_AlgoTools.hxx>
40 #include <GEOMAlgo_KindOfName.hxx>
41 #include <GEOMAlgo_ShapeInfoFiller.hxx>
43 #include <GEOM_PythonDump.hxx>
45 #include <utilities.h>
48 #include <Bnd_Box.hxx>
49 #include <BOPAlgo_CheckerSI.hxx>
50 #include <TopTools_ListOfShape.hxx>
51 #include <BOPDS_DS.hxx>
52 #include <BOPDS_MapOfPair.hxx>
53 #include <BOPDS_Pair.hxx>
54 #include <BOPTools_AlgoTools.hxx>
55 #include <BRepBndLib.hxx>
56 #include <BRepBuilderAPI_Copy.hxx>
57 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
58 #include <BRepCheck_Shell.hxx>
59 #include <BRepClass3d_SolidClassifier.hxx>
60 #include <BRepClass_FaceClassifier.hxx>
61 #include <BRepExtrema_DistShapeShape.hxx>
62 #include <BRepExtrema_ShapeProximity.hxx>
63 #include <BRepExtrema_SelfIntersection.hxx>
64 #include <BRepExtrema_MapOfIntegerPackedMapOfInteger.hxx>
65 #include <BRepGProp.hxx>
66 #include <BRepTools.hxx>
67 #include <BRep_Tool.hxx>
68 #include <Geom_Line.hxx>
69 #include <GeomAPI_ProjectPointOnCurve.hxx>
70 #include <GeomAPI_ProjectPointOnSurf.hxx>
71 #include <GeomLProp_CLProps.hxx>
72 #include <GeomLProp_SLProps.hxx>
73 #include <Geom_Plane.hxx>
74 #include <GProp_GProps.hxx>
75 #include <GProp_PrincipalProps.hxx>
76 #include <ShapeAnalysis.hxx>
77 #include <ShapeAnalysis_Surface.hxx>
79 #include <TopExp_Explorer.hxx>
81 #include <TopoDS_Edge.hxx>
82 #include <TopTools_IndexedMapOfShape.hxx>
83 #include <TopTools_DataMapIteratorOfDataMapOfIntegerListOfShape.hxx>
84 #include <TColStd_MapIteratorOfPackedMapOfInteger.hxx>
85 #include <TopTools_ListIteratorOfListOfShape.hxx>
86 #include <TopTools_ListOfShape.hxx>
87 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
91 //=============================================================================
95 //=============================================================================
96 GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations (GEOM_Engine* theEngine)
97 : GEOM_IOperations(theEngine)
99 MESSAGE("GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations");
102 //=============================================================================
106 //=============================================================================
107 GEOMImpl_IMeasureOperations::~GEOMImpl_IMeasureOperations()
109 MESSAGE("GEOMImpl_IMeasureOperations::~GEOMImpl_IMeasureOperations");
112 //=============================================================================
113 /*! Get kind and parameters of the given shape.
115 //=============================================================================
116 GEOMImpl_IMeasureOperations::ShapeKind GEOMImpl_IMeasureOperations::KindOfShape
117 (Handle(GEOM_Object) theShape,
118 Handle(TColStd_HSequenceOfInteger)& theIntegers,
119 Handle(TColStd_HSequenceOfReal)& theDoubles)
122 ShapeKind aKind = SK_NO_SHAPE;
124 if (theIntegers.IsNull()) theIntegers = new TColStd_HSequenceOfInteger;
125 else theIntegers->Clear();
127 if (theDoubles.IsNull()) theDoubles = new TColStd_HSequenceOfReal;
128 else theDoubles->Clear();
130 if (theShape.IsNull())
133 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
134 if (aRefShape.IsNull()) return aKind;
136 TopoDS_Shape aShape = aRefShape->GetValue();
137 if (aShape.IsNull()) return aKind;
139 int geom_type = theShape->GetType();
141 // check if it's advanced shape
142 if ( geom_type > USER_TYPE ) {
148 GEOMAlgo_ShapeInfoFiller aSF;
149 aSF.SetShape(aShape);
152 Standard_Integer iErr = aSF.ErrorStatus();
155 SetErrorCode("Error in GEOMAlgo_ShapeInfoFiller");
158 const GEOMAlgo_ShapeInfo& anInfo = aSF.Info();
160 // specific processing for some "advanced" objects
161 switch ( geom_type ) {
163 // local coordinate system
164 // (+) geompy.kind.LCS xc yc zc xx xy xz yx yy yz zx zy zz
166 TopoDS_Face aFace = TopoDS::Face( aShape );
167 Handle(Geom_Plane) aPlane = Handle(Geom_Plane)::DownCast( BRep_Tool::Surface( aFace ) );
168 gp_Pnt aC = aPlane->Pln().Location();
169 gp_Ax3 anAx3 = aPlane->Pln().Position();
171 theDoubles->Append(aC.X());
172 theDoubles->Append(aC.Y());
173 theDoubles->Append(aC.Z());
175 gp_Dir aD = anAx3.XDirection();
176 theDoubles->Append(aD.X());
177 theDoubles->Append(aD.Y());
178 theDoubles->Append(aD.Z());
179 aD = anAx3.YDirection();
180 theDoubles->Append(aD.X());
181 theDoubles->Append(aD.Y());
182 theDoubles->Append(aD.Z());
183 aD = anAx3.Direction();
184 theDoubles->Append(aD.X());
185 theDoubles->Append(aD.Y());
186 theDoubles->Append(aD.Z());
193 TopAbs_ShapeEnum aType = anInfo.Type();
196 case TopAbs_COMPOUND:
197 case TopAbs_COMPSOLID:
199 // (+) geompy.kind.COMPOUND nb_solids nb_faces nb_edges nb_vertices
200 // (+) geompy.kind.COMPSOLID nb_solids nb_faces nb_edges nb_vertices
201 // ??? "nb_faces" - all faces or only 'standalone' faces?
202 if (aType == TopAbs_COMPOUND)
205 aKind = SK_COMPSOLID;
207 //theIntegers->Append(anInfo.NbSubShapes(TopAbs_COMPOUND));
208 //theIntegers->Append(anInfo.NbSubShapes(TopAbs_COMPSOLID));
209 theIntegers->Append(anInfo.NbSubShapes(TopAbs_SOLID));
210 theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
211 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
212 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
218 // (+) geompy.kind.SHELL geompy.info.closed nb_faces nb_edges nb_vertices
219 // (+) geompy.kind.SHELL geompy.info.unclosed nb_faces nb_edges nb_vertices
222 theIntegers->Append((int)anInfo.KindOfClosed());
224 theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
225 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
226 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
232 // (+) geompy.kind.WIRE geompy.info.closed nb_edges nb_vertices
233 // (+) geompy.kind.WIRE geompy.info.unclosed nb_edges nb_vertices
236 theIntegers->Append((int)anInfo.KindOfClosed());
238 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
239 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
247 GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
250 case GEOMAlgo_KN_SPHERE:
251 // (+) geompy.kind.SPHERE xc yc zc R
255 gp_Pnt aC = anInfo.Location();
256 theDoubles->Append(aC.X());
257 theDoubles->Append(aC.Y());
258 theDoubles->Append(aC.Z());
260 theDoubles->Append(anInfo.Radius1());
263 case GEOMAlgo_KN_CYLINDER:
264 // (+) geompy.kind.CYLINDER xb yb zb dx dy dz R H
268 gp_Pnt aC = anInfo.Location();
269 theDoubles->Append(aC.X());
270 theDoubles->Append(aC.Y());
271 theDoubles->Append(aC.Z());
273 gp_Ax3 anAx3 = anInfo.Position();
274 gp_Dir aD = anAx3.Direction();
275 theDoubles->Append(aD.X());
276 theDoubles->Append(aD.Y());
277 theDoubles->Append(aD.Z());
279 theDoubles->Append(anInfo.Radius1());
280 theDoubles->Append(anInfo.Height());
283 case GEOMAlgo_KN_BOX:
284 // (+) geompy.kind.BOX xc yc zc ax ay az
288 gp_Pnt aC = anInfo.Location();
289 theDoubles->Append(aC.X());
290 theDoubles->Append(aC.Y());
291 theDoubles->Append(aC.Z());
293 gp_Ax3 anAx3 = anInfo.Position();
294 gp_Dir aD = anAx3.Direction();
295 gp_Dir aX = anAx3.XDirection();
298 if (aD.IsParallel(gp::DZ(), Precision::Angular()) &&
299 aX.IsParallel(gp::DX(), Precision::Angular())) {
300 theDoubles->Append(anInfo.Length()); // ax'
301 theDoubles->Append(anInfo.Width()); // ay'
302 theDoubles->Append(anInfo.Height()); // az'
304 else if (aD.IsParallel(gp::DZ(), Precision::Angular()) &&
305 aX.IsParallel(gp::DY(), Precision::Angular())) {
306 theDoubles->Append(anInfo.Width()); // ay'
307 theDoubles->Append(anInfo.Length()); // ax'
308 theDoubles->Append(anInfo.Height()); // az'
310 else if (aD.IsParallel(gp::DX(), Precision::Angular()) &&
311 aX.IsParallel(gp::DZ(), Precision::Angular())) {
312 theDoubles->Append(anInfo.Height()); // az'
313 theDoubles->Append(anInfo.Width()); // ay'
314 theDoubles->Append(anInfo.Length()); // ax'
316 else if (aD.IsParallel(gp::DX(), Precision::Angular()) &&
317 aX.IsParallel(gp::DY(), Precision::Angular())) {
318 theDoubles->Append(anInfo.Height()); // az'
319 theDoubles->Append(anInfo.Length()); // ax'
320 theDoubles->Append(anInfo.Width()); // ay'
322 else if (aD.IsParallel(gp::DY(), Precision::Angular()) &&
323 aX.IsParallel(gp::DZ(), Precision::Angular())) {
324 theDoubles->Append(anInfo.Width()); // ay'
325 theDoubles->Append(anInfo.Height()); // az'
326 theDoubles->Append(anInfo.Length()); // ax'
328 else if (aD.IsParallel(gp::DY(), Precision::Angular()) &&
329 aX.IsParallel(gp::DX(), Precision::Angular())) {
330 theDoubles->Append(anInfo.Length()); // ax'
331 theDoubles->Append(anInfo.Height()); // az'
332 theDoubles->Append(anInfo.Width()); // ay'
335 // (+) geompy.kind.ROTATED_BOX xo yo zo zx zy zz xx xy xz ax ay az
336 aKind = SK_ROTATED_BOX;
338 // Direction and XDirection
339 theDoubles->Append(aD.X());
340 theDoubles->Append(aD.Y());
341 theDoubles->Append(aD.Z());
343 theDoubles->Append(aX.X());
344 theDoubles->Append(aX.Y());
345 theDoubles->Append(aX.Z());
348 theDoubles->Append(anInfo.Length());
349 theDoubles->Append(anInfo.Width());
350 theDoubles->Append(anInfo.Height());
354 case GEOMAlgo_KN_TORUS:
355 // (+) geompy.kind.TORUS xc yc zc dx dy dz R_1 R_2
359 gp_Pnt aO = anInfo.Location();
360 theDoubles->Append(aO.X());
361 theDoubles->Append(aO.Y());
362 theDoubles->Append(aO.Z());
364 gp_Ax3 anAx3 = anInfo.Position();
365 gp_Dir aD = anAx3.Direction();
366 theDoubles->Append(aD.X());
367 theDoubles->Append(aD.Y());
368 theDoubles->Append(aD.Z());
370 theDoubles->Append(anInfo.Radius1());
371 theDoubles->Append(anInfo.Radius2());
374 case GEOMAlgo_KN_CONE:
375 // (+) geompy.kind.CONE xb yb zb dx dy dz R_1 R_2 H
379 gp_Pnt aO = anInfo.Location();
380 theDoubles->Append(aO.X());
381 theDoubles->Append(aO.Y());
382 theDoubles->Append(aO.Z());
384 gp_Ax3 anAx3 = anInfo.Position();
385 gp_Dir aD = anAx3.Direction();
386 theDoubles->Append(aD.X());
387 theDoubles->Append(aD.Y());
388 theDoubles->Append(aD.Z());
390 theDoubles->Append(anInfo.Radius1());
391 theDoubles->Append(anInfo.Radius2());
392 theDoubles->Append(anInfo.Height());
395 case GEOMAlgo_KN_POLYHEDRON:
396 // (+) geompy.kind.POLYHEDRON nb_faces nb_edges nb_vertices
398 aKind = SK_POLYHEDRON;
400 theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
401 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
402 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
406 // (+) geompy.kind.SOLID nb_faces nb_edges nb_vertices
408 theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
409 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
410 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
420 GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
422 case GEOMAlgo_KN_SPHERE:
423 // (+) geompy.kind.SPHERE2D xc yc zc R
427 gp_Pnt aC = anInfo.Location();
428 theDoubles->Append(aC.X());
429 theDoubles->Append(aC.Y());
430 theDoubles->Append(aC.Z());
432 theDoubles->Append(anInfo.Radius1());
435 case GEOMAlgo_KN_CYLINDER:
436 // (+) geompy.kind.CYLINDER2D xb yb zb dx dy dz R H
438 aKind = SK_CYLINDER2D;
440 gp_Pnt aO = anInfo.Location();
441 theDoubles->Append(aO.X());
442 theDoubles->Append(aO.Y());
443 theDoubles->Append(aO.Z());
445 gp_Ax3 anAx3 = anInfo.Position();
446 gp_Dir aD = anAx3.Direction();
447 theDoubles->Append(aD.X());
448 theDoubles->Append(aD.Y());
449 theDoubles->Append(aD.Z());
451 theDoubles->Append(anInfo.Radius1());
452 theDoubles->Append(anInfo.Height());
455 case GEOMAlgo_KN_TORUS:
456 // (+) geompy.kind.TORUS2D xc yc zc dx dy dz R_1 R_2
460 gp_Pnt aO = anInfo.Location();
461 theDoubles->Append(aO.X());
462 theDoubles->Append(aO.Y());
463 theDoubles->Append(aO.Z());
465 gp_Ax3 anAx3 = anInfo.Position();
466 gp_Dir aD = anAx3.Direction();
467 theDoubles->Append(aD.X());
468 theDoubles->Append(aD.Y());
469 theDoubles->Append(aD.Z());
471 theDoubles->Append(anInfo.Radius1());
472 theDoubles->Append(anInfo.Radius2());
475 case GEOMAlgo_KN_CONE:
476 // (+) geompy.kind.CONE2D xc yc zc dx dy dz R_1 R_2 H
480 gp_Pnt aO = anInfo.Location();
481 theDoubles->Append(aO.X());
482 theDoubles->Append(aO.Y());
483 theDoubles->Append(aO.Z());
485 gp_Ax3 anAx3 = anInfo.Position();
486 gp_Dir aD = anAx3.Direction();
487 theDoubles->Append(aD.X());
488 theDoubles->Append(aD.Y());
489 theDoubles->Append(aD.Z());
491 theDoubles->Append(anInfo.Radius1());
492 theDoubles->Append(anInfo.Radius2());
493 theDoubles->Append(anInfo.Height());
496 case GEOMAlgo_KN_DISKCIRCLE:
497 // (+) geompy.kind.DISK_CIRCLE xc yc zc dx dy dz R
499 aKind = SK_DISK_CIRCLE;
501 gp_Pnt aC = anInfo.Location();
502 theDoubles->Append(aC.X());
503 theDoubles->Append(aC.Y());
504 theDoubles->Append(aC.Z());
506 gp_Ax3 anAx3 = anInfo.Position();
507 gp_Dir aD = anAx3.Direction();
508 theDoubles->Append(aD.X());
509 theDoubles->Append(aD.Y());
510 theDoubles->Append(aD.Z());
512 theDoubles->Append(anInfo.Radius1());
515 case GEOMAlgo_KN_DISKELLIPSE:
516 // (+) geompy.kind.DISK_ELLIPSE xc yc zc dx dy dz R_1 R_2
518 aKind = SK_DISK_ELLIPSE;
520 gp_Pnt aC = anInfo.Location();
521 theDoubles->Append(aC.X());
522 theDoubles->Append(aC.Y());
523 theDoubles->Append(aC.Z());
525 gp_Ax3 anAx3 = anInfo.Position();
526 gp_Dir aD = anAx3.Direction();
527 theDoubles->Append(aD.X());
528 theDoubles->Append(aD.Y());
529 theDoubles->Append(aD.Z());
531 theDoubles->Append(anInfo.Radius1());
532 theDoubles->Append(anInfo.Radius2());
535 case GEOMAlgo_KN_RECTANGLE:
536 case GEOMAlgo_KN_TRIANGLE:
537 case GEOMAlgo_KN_QUADRANGLE:
538 case GEOMAlgo_KN_POLYGON:
539 // (+) geompy.kind.POLYGON xo yo zo dx dy dz nb_edges nb_vertices
543 gp_Pnt aO = anInfo.Location();
544 theDoubles->Append(aO.X());
545 theDoubles->Append(aO.Y());
546 theDoubles->Append(aO.Z());
548 gp_Ax3 anAx3 = anInfo.Position();
549 gp_Dir aD = anAx3.Direction();
550 theDoubles->Append(aD.X());
551 theDoubles->Append(aD.Y());
552 theDoubles->Append(aD.Z());
554 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
555 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
558 case GEOMAlgo_KN_PLANE: // infinite
559 // (+) geompy.kind.PLANE xo yo zo dx dy dz
563 gp_Pnt aC = anInfo.Location();
564 theDoubles->Append(aC.X());
565 theDoubles->Append(aC.Y());
566 theDoubles->Append(aC.Z());
568 gp_Ax3 anAx3 = anInfo.Position();
569 gp_Dir aD = anAx3.Direction();
570 theDoubles->Append(aD.X());
571 theDoubles->Append(aD.Y());
572 theDoubles->Append(aD.Z());
574 if (anInfo.KindOfBounds() != GEOMAlgo_KB_INFINITE)
576 // (+) geompy.kind.PLANAR xo yo zo dx dy dz nb_edges nb_vertices
579 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
580 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
585 // ??? geompy.kind.FACE nb_edges nb_vertices _surface_type_id_
586 // (+) geompy.kind.FACE nb_edges nb_vertices
587 theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
588 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
597 GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
599 case GEOMAlgo_KN_CIRCLE:
601 // (+) geompy.kind.CIRCLE xc yc zc dx dy dz R
604 gp_Pnt aC = anInfo.Location();
605 theDoubles->Append(aC.X());
606 theDoubles->Append(aC.Y());
607 theDoubles->Append(aC.Z());
609 gp_Ax3 anAx3 = anInfo.Position();
610 gp_Dir aD = anAx3.Direction();
611 theDoubles->Append(aD.X());
612 theDoubles->Append(aD.Y());
613 theDoubles->Append(aD.Z());
615 theDoubles->Append(anInfo.Radius1());
618 case GEOMAlgo_KN_ARCCIRCLE:
620 // (+) geompy.kind.ARC_CIRCLE xc yc zc dx dy dz R x1 y1 z1 x2 y2 z2
621 aKind = SK_ARC_CIRCLE;
623 gp_Pnt aC = anInfo.Location();
624 theDoubles->Append(aC.X());
625 theDoubles->Append(aC.Y());
626 theDoubles->Append(aC.Z());
628 gp_Ax3 anAx3 = anInfo.Position();
629 gp_Dir aD = anAx3.Direction();
630 theDoubles->Append(aD.X());
631 theDoubles->Append(aD.Y());
632 theDoubles->Append(aD.Z());
634 theDoubles->Append(anInfo.Radius1());
636 gp_Pnt aP1 = anInfo.Pnt1();
637 theDoubles->Append(aP1.X());
638 theDoubles->Append(aP1.Y());
639 theDoubles->Append(aP1.Z());
641 gp_Pnt aP2 = anInfo.Pnt2();
642 theDoubles->Append(aP2.X());
643 theDoubles->Append(aP2.Y());
644 theDoubles->Append(aP2.Z());
647 case GEOMAlgo_KN_ELLIPSE:
649 // (+) geompy.kind.ELLIPSE xc yc zc dx dy dz R_1 R_2 xVx yVx zVx xVy yVy zVy
652 gp_Pnt aC = anInfo.Location();
653 theDoubles->Append(aC.X());
654 theDoubles->Append(aC.Y());
655 theDoubles->Append(aC.Z());
657 gp_Ax3 anAx3 = anInfo.Position();
658 gp_Dir aD = anAx3.Direction();
659 theDoubles->Append(aD.X());
660 theDoubles->Append(aD.Y());
661 theDoubles->Append(aD.Z());
663 theDoubles->Append(anInfo.Radius1());
664 theDoubles->Append(anInfo.Radius2());
666 gp_Dir aXD = anAx3.XDirection();
667 theDoubles->Append(aXD.X());
668 theDoubles->Append(aXD.Y());
669 theDoubles->Append(aXD.Z());
671 gp_Dir aYD = anAx3.YDirection();
672 theDoubles->Append(aYD.X());
673 theDoubles->Append(aYD.Y());
674 theDoubles->Append(aYD.Z());
677 case GEOMAlgo_KN_ARCELLIPSE:
679 // (+) geompy.kind.ARC_ELLIPSE xc yc zc dx dy dz R_1 R_2 x1 y1 z1 x2 y2 z2 xVx yVx zVx xVy yVy zVy
680 aKind = SK_ARC_ELLIPSE;
682 gp_Pnt aC = anInfo.Location();
683 theDoubles->Append(aC.X());
684 theDoubles->Append(aC.Y());
685 theDoubles->Append(aC.Z());
687 gp_Ax3 anAx3 = anInfo.Position();
688 gp_Dir aD = anAx3.Direction();
689 theDoubles->Append(aD.X());
690 theDoubles->Append(aD.Y());
691 theDoubles->Append(aD.Z());
693 theDoubles->Append(anInfo.Radius1());
694 theDoubles->Append(anInfo.Radius2());
696 gp_Pnt aP1 = anInfo.Pnt1();
697 theDoubles->Append(aP1.X());
698 theDoubles->Append(aP1.Y());
699 theDoubles->Append(aP1.Z());
701 gp_Pnt aP2 = anInfo.Pnt2();
702 theDoubles->Append(aP2.X());
703 theDoubles->Append(aP2.Y());
704 theDoubles->Append(aP2.Z());
706 gp_Dir aXD = anAx3.XDirection();
707 theDoubles->Append(aXD.X());
708 theDoubles->Append(aXD.Y());
709 theDoubles->Append(aXD.Z());
711 gp_Dir aYD = anAx3.YDirection();
712 theDoubles->Append(aYD.X());
713 theDoubles->Append(aYD.Y());
714 theDoubles->Append(aYD.Z());
717 case GEOMAlgo_KN_LINE:
719 // ??? geompy.kind.LINE x1 y1 z1 x2 y2 z2
720 // (+) geompy.kind.LINE x1 y1 z1 dx dy dz
723 gp_Pnt aO = anInfo.Location();
724 theDoubles->Append(aO.X());
725 theDoubles->Append(aO.Y());
726 theDoubles->Append(aO.Z());
728 gp_Dir aD = anInfo.Direction();
729 theDoubles->Append(aD.X());
730 theDoubles->Append(aD.Y());
731 theDoubles->Append(aD.Z());
734 case GEOMAlgo_KN_SEGMENT:
736 // (+) geompy.kind.SEGMENT x1 y1 z1 x2 y2 z2
739 gp_Pnt aP1 = anInfo.Pnt1();
740 theDoubles->Append(aP1.X());
741 theDoubles->Append(aP1.Y());
742 theDoubles->Append(aP1.Z());
744 gp_Pnt aP2 = anInfo.Pnt2();
745 theDoubles->Append(aP2.X());
746 theDoubles->Append(aP2.Y());
747 theDoubles->Append(aP2.Z());
750 case GEOMAlgo_KN_CURVEBSPLINE:
752 // (+) geompy.kind.CRV_BSPLINE p d np nk nw nm x1 y1 z1 ... xnp ynp znp k1 ... knk w1 ... wnw m1 ... mnm
753 aKind = SK_CRV_BSPLINE;
754 Standard_Integer aNbPoles = anInfo.NbPoles();
755 Standard_Integer aNbKnots = anInfo.NbKnots();
756 Standard_Integer aNbWeights = anInfo.NbWeights();
757 Standard_Integer aNbMultiplicities = anInfo.NbMultiplicities();
759 theIntegers->Append(anInfo.KindOfPeriod() == GEOMAlgo_KP_PERIODIC ? 1 : 0);
760 theIntegers->Append(anInfo.Degree());
761 theIntegers->Append(aNbPoles);
762 theIntegers->Append(aNbKnots);
763 theIntegers->Append(aNbWeights);
764 theIntegers->Append(aNbMultiplicities);
768 Handle(TColgp_HArray1OfPnt) aPoles = anInfo.Poles();
769 if (aPoles.IsNull() || aPoles->Length() != aNbPoles) {
770 SetErrorCode("B-Spline Curve: no or wrong number of poles given");
773 for (i=1; i<=aNbPoles; i++) {
774 const gp_Pnt &aP = aPoles->Value(i);
775 theDoubles->Append(aP.X());
776 theDoubles->Append(aP.Y());
777 theDoubles->Append(aP.Z());
782 Handle(TColStd_HArray1OfReal) aKnots = anInfo.Knots();
783 if (aKnots.IsNull() || aKnots->Length() != aNbKnots) {
784 SetErrorCode("B-Spline Curve: no or wrong number of knots given");
787 for (i=1; i<=aNbKnots; i++)
788 theDoubles->Append(aKnots->Value(i));
791 if (aNbWeights > 0) {
792 Handle(TColStd_HArray1OfReal) aWeights = anInfo.Weights();
793 if (aNbWeights > 0 && (aWeights.IsNull() || aWeights->Length() != aNbWeights)) {
794 SetErrorCode("B-Spline Curve: no or wrong number of weights given");
797 for (i=1; i<=aNbWeights; i++)
798 theDoubles->Append(aWeights->Value(i));
801 if (aNbMultiplicities > 0) {
802 Handle(TColStd_HArray1OfInteger) aMults = anInfo.Multiplicities();
803 if (aMults.IsNull() || aMults->Length() != aNbMultiplicities) {
804 SetErrorCode("B-Spline Curve: no or wrong number of multiplicities given");
807 for (i=1; i<=aNbMultiplicities; i++)
808 theIntegers->Append(aMults->Value(i));
812 case GEOMAlgo_KN_CURVEBEZIER:
814 // (+) geompy.kind.CRV_BEZIER np nw x1 y1 z1 ... xnp ynp znp w1 ... wnw
815 aKind = SK_CRV_BEZIER;
816 Standard_Integer aNbPoles = anInfo.NbPoles();
817 Standard_Integer aNbWeights = anInfo.NbWeights();
819 theIntegers->Append(aNbPoles);
820 theIntegers->Append(aNbWeights);
824 Handle(TColgp_HArray1OfPnt) aPoles = anInfo.Poles();
825 if (aPoles.IsNull() || aPoles->Length() != aNbPoles) {
826 SetErrorCode("Bezier Curve: no or wrong number of poles given");
829 for (i=1; i<=aNbPoles; i++) {
830 const gp_Pnt &aP = aPoles->Value(i);
831 theDoubles->Append(aP.X());
832 theDoubles->Append(aP.Y());
833 theDoubles->Append(aP.Z());
837 if (aNbWeights > 0) {
838 Handle(TColStd_HArray1OfReal) aWeights = anInfo.Weights();
839 if (aNbWeights > 0 && (aWeights.IsNull() || aWeights->Length() != aNbWeights)) {
840 SetErrorCode("B-Spline Curve: no or wrong number of weights given");
843 for (i=1; i<=aNbWeights; i++)
844 theDoubles->Append(aWeights->Value(i));
848 case GEOMAlgo_KN_HYPERBOLA:
850 // (+) geompy.kind.HYPERBOLA xc yc zc dx dy dz R_1 R_2 xVx yVx zVx xVy yVy zVy
851 aKind = SK_HYPERBOLA;
853 gp_Pnt aC = anInfo.Location();
854 theDoubles->Append(aC.X());
855 theDoubles->Append(aC.Y());
856 theDoubles->Append(aC.Z());
858 gp_Ax3 anAx3 = anInfo.Position();
859 gp_Dir aD = anAx3.Direction();
860 theDoubles->Append(aD.X());
861 theDoubles->Append(aD.Y());
862 theDoubles->Append(aD.Z());
864 theDoubles->Append(anInfo.Radius1());
865 theDoubles->Append(anInfo.Radius2());
867 gp_Dir aXD = anAx3.XDirection();
868 theDoubles->Append(aXD.X());
869 theDoubles->Append(aXD.Y());
870 theDoubles->Append(aXD.Z());
872 gp_Dir aYD = anAx3.YDirection();
873 theDoubles->Append(aYD.X());
874 theDoubles->Append(aYD.Y());
875 theDoubles->Append(aYD.Z());
878 case GEOMAlgo_KN_PARABOLA:
880 // (+) geompy.kind.PARABOLA xc yc zc dx dy dz F xVx yVx zVx xVy yVy zVy
883 gp_Pnt aC = anInfo.Location();
884 theDoubles->Append(aC.X());
885 theDoubles->Append(aC.Y());
886 theDoubles->Append(aC.Z());
888 gp_Ax3 anAx3 = anInfo.Position();
889 gp_Dir aD = anAx3.Direction();
890 theDoubles->Append(aD.X());
891 theDoubles->Append(aD.Y());
892 theDoubles->Append(aD.Z());
894 theDoubles->Append(anInfo.Radius1());
896 gp_Dir aXD = anAx3.XDirection();
897 theDoubles->Append(aXD.X());
898 theDoubles->Append(aXD.Y());
899 theDoubles->Append(aXD.Z());
901 gp_Dir aYD = anAx3.YDirection();
902 theDoubles->Append(aYD.X());
903 theDoubles->Append(aYD.Y());
904 theDoubles->Append(aYD.Z());
908 // ??? geompy.kind.EDGE nb_vertices _curve_type_id_
909 // (+) geompy.kind.EDGE nb_vertices
910 theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
917 // (+) geompy.kind.VERTEX x y z
920 gp_Pnt aP = anInfo.Location();
921 theDoubles->Append(aP.X());
922 theDoubles->Append(aP.Y());
923 theDoubles->Append(aP.Z());
933 //=============================================================================
937 //=============================================================================
938 void GEOMImpl_IMeasureOperations::GetPosition
939 (Handle(GEOM_Object) theShape,
940 Standard_Real& Ox, Standard_Real& Oy, Standard_Real& Oz,
941 Standard_Real& Zx, Standard_Real& Zy, Standard_Real& Zz,
942 Standard_Real& Xx, Standard_Real& Xy, Standard_Real& Xz)
946 //Set default values: global CS
947 Ox = Oy = Oz = Zx = Zy = Xy = Xz = 0.;
950 if (theShape.IsNull()) return;
952 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
953 if (aRefShape.IsNull()) return;
955 TopoDS_Shape aShape = aRefShape->GetValue();
956 if (aShape.IsNull()) {
957 SetErrorCode("The Objects has NULL Shape");
964 gp_Ax3 anAx3 = GEOMUtils::GetPosition(aShape);
966 gp_Pnt anOri = anAx3.Location();
967 gp_Dir aDirZ = anAx3.Direction();
968 gp_Dir aDirX = anAx3.XDirection();
971 anOri.Coord(Ox, Oy, Oz);
972 aDirZ.Coord(Zx, Zy, Zz);
973 aDirX.Coord(Xx, Xy, Xz);
975 catch (Standard_Failure& aFail) {
976 SetErrorCode(aFail.GetMessageString());
983 //=============================================================================
987 //=============================================================================
988 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetCentreOfMass
989 (Handle(GEOM_Object) theShape)
993 if (theShape.IsNull()) return NULL;
995 //Add a new CentreOfMass object
996 Handle(GEOM_Object) aCDG = GetEngine()->AddObject(GEOM_CDG);
998 //Add a new CentreOfMass function
999 Handle(GEOM_Function) aFunction =
1000 aCDG->AddFunction(GEOMImpl_MeasureDriver::GetID(), CDG_MEASURE);
1001 if (aFunction.IsNull()) return NULL;
1003 //Check if the function is set correctly
1004 if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
1006 GEOMImpl_IMeasure aCI (aFunction);
1008 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1009 if (aRefShape.IsNull()) return NULL;
1011 aCI.SetBase(aRefShape);
1013 //Compute the CentreOfMass value
1016 if (!GetSolver()->ComputeFunction(aFunction)) {
1017 SetErrorCode("Measure driver failed to compute centre of mass");
1021 catch (Standard_Failure& aFail) {
1022 SetErrorCode(aFail.GetMessageString());
1026 //Make a Python command
1027 GEOM::TPythonDump(aFunction) << aCDG << " = geompy.MakeCDG(" << theShape << ")";
1033 //=============================================================================
1037 //=============================================================================
1038 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetVertexByIndex
1039 (Handle(GEOM_Object) theShape,
1040 Standard_Integer theIndex,
1041 Standard_Boolean theUseOri)
1045 if (theShape.IsNull()) return NULL;
1047 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1048 if (aRefShape.IsNull()) return NULL;
1050 //Add a new Vertex object
1051 Handle(GEOM_Object) aVertex = GetEngine()->AddObject(GEOM_POINT);
1054 Handle(GEOM_Function) aFunction =
1055 aVertex->AddFunction(GEOMImpl_MeasureDriver::GetID(), VERTEX_BY_INDEX);
1056 if (aFunction.IsNull()) return NULL;
1058 //Check if the function is set correctly
1059 if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
1061 GEOMImpl_IMeasure aCI (aFunction);
1062 aCI.SetBase(aRefShape);
1063 aCI.SetIndex(theIndex);
1064 aCI.SetUseOri(theUseOri);
1069 if (!GetSolver()->ComputeFunction(aFunction)) {
1070 SetErrorCode("Vertex by index driver failed.");
1074 catch (Standard_Failure& aFail) {
1075 SetErrorCode(aFail.GetMessageString());
1079 //Make a Python command
1080 GEOM::TPythonDump(aFunction) << aVertex << " = geompy.GetVertexByIndex("
1083 << theUseOri << ")";
1089 //=============================================================================
1093 //=============================================================================
1094 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetNormal
1095 (Handle(GEOM_Object) theFace,
1096 Handle(GEOM_Object) theOptionalPoint)
1100 if (theFace.IsNull()) return NULL;
1102 //Add a new Normale object
1103 Handle(GEOM_Object) aNorm = GetEngine()->AddObject(GEOM_VECTOR);
1105 //Add a new Normale function
1106 Handle(GEOM_Function) aFunction =
1107 aNorm->AddFunction(GEOMImpl_MeasureDriver::GetID(), VECTOR_FACE_NORMALE);
1108 if (aFunction.IsNull()) return NULL;
1110 //Check if the function is set correctly
1111 if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
1113 GEOMImpl_IMeasure aCI (aFunction);
1115 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
1116 if (aFace.IsNull()) return NULL;
1120 if (!theOptionalPoint.IsNull()) {
1121 Handle(GEOM_Function) anOptPnt = theOptionalPoint->GetLastFunction();
1122 aCI.SetPoint(anOptPnt);
1125 //Compute the Normale value
1128 if (!GetSolver()->ComputeFunction(aFunction)) {
1129 SetErrorCode("Measure driver failed to compute normake of face");
1133 catch (Standard_Failure& aFail) {
1134 SetErrorCode(aFail.GetMessageString());
1138 //Make a Python command
1139 GEOM::TPythonDump pd (aFunction);
1140 pd << aNorm << " = geompy.GetNormal(" << theFace;
1141 if (!theOptionalPoint.IsNull()) {
1142 pd << ", " << theOptionalPoint;
1150 //=============================================================================
1152 * GetBasicProperties
1154 //=============================================================================
1155 void GEOMImpl_IMeasureOperations::GetBasicProperties (Handle(GEOM_Object) theShape,
1156 const Standard_Real theTolerance,
1157 Standard_Real& theLength,
1158 Standard_Real& theSurfArea,
1159 Standard_Real& theVolume)
1163 if (theShape.IsNull()) return;
1165 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1166 if (aRefShape.IsNull()) return;
1168 TopoDS_Shape aShape = aRefShape->GetValue();
1169 if (aShape.IsNull()) {
1170 SetErrorCode("The Objects has NULL Shape");
1174 //Compute the parameters
1175 GProp_GProps LProps, SProps;
1176 Standard_Real anEps = theTolerance >= 0 ? theTolerance : 1.e-6;
1179 BRepGProp::LinearProperties(aShape, LProps, Standard_True);
1180 theLength = LProps.Mass();
1182 BRepGProp::SurfaceProperties(aShape, SProps, anEps, Standard_True);
1183 theSurfArea = SProps.Mass();
1186 if (aShape.ShapeType() < TopAbs_SHELL) {
1187 for (TopExp_Explorer Exp (aShape, TopAbs_SOLID); Exp.More(); Exp.Next()) {
1188 GProp_GProps VProps;
1189 BRepGProp::VolumeProperties(Exp.Current(), VProps, anEps, Standard_True);
1190 theVolume += VProps.Mass();
1194 catch (Standard_Failure& aFail) {
1195 SetErrorCode(aFail.GetMessageString());
1202 //=============================================================================
1206 //=============================================================================
1207 void GEOMImpl_IMeasureOperations::GetInertia
1208 (Handle(GEOM_Object) theShape,
1209 Standard_Real& I11, Standard_Real& I12, Standard_Real& I13,
1210 Standard_Real& I21, Standard_Real& I22, Standard_Real& I23,
1211 Standard_Real& I31, Standard_Real& I32, Standard_Real& I33,
1212 Standard_Real& Ix , Standard_Real& Iy , Standard_Real& Iz)
1216 if (theShape.IsNull()) return;
1218 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1219 if (aRefShape.IsNull()) return;
1221 TopoDS_Shape aShape = aRefShape->GetValue();
1222 if (aShape.IsNull()) {
1223 SetErrorCode("The Objects has NULL Shape");
1227 //Compute the parameters
1228 GProp_GProps System;
1232 if (aShape.ShapeType() == TopAbs_VERTEX ||
1233 aShape.ShapeType() == TopAbs_EDGE ||
1234 aShape.ShapeType() == TopAbs_WIRE) {
1235 BRepGProp::LinearProperties(aShape, System, Standard_True);
1236 } else if (aShape.ShapeType() == TopAbs_FACE ||
1237 aShape.ShapeType() == TopAbs_SHELL) {
1238 BRepGProp::SurfaceProperties(aShape, System, Standard_True);
1240 BRepGProp::VolumeProperties(aShape, System, Standard_True);
1242 gp_Mat I = System.MatrixOfInertia();
1256 GProp_PrincipalProps Pr = System.PrincipalProperties();
1257 Pr.Moments(Ix,Iy,Iz);
1259 catch (Standard_Failure& aFail) {
1260 SetErrorCode(aFail.GetMessageString());
1267 //=============================================================================
1271 //=============================================================================
1272 void GEOMImpl_IMeasureOperations::GetBoundingBox
1273 (Handle(GEOM_Object) theShape,
1274 const Standard_Boolean precise,
1275 Standard_Real& Xmin, Standard_Real& Xmax,
1276 Standard_Real& Ymin, Standard_Real& Ymax,
1277 Standard_Real& Zmin, Standard_Real& Zmax)
1281 if (theShape.IsNull()) return;
1283 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1284 if (aRefShape.IsNull()) return;
1286 TopoDS_Shape aShape = aRefShape->GetValue();
1287 if (aShape.IsNull()) {
1288 SetErrorCode("The Objects has NULL Shape");
1292 //Compute the parameters
1297 BRepBuilderAPI_Copy aCopyTool (aShape);
1298 if (!aCopyTool.IsDone()) {
1299 SetErrorCode("GetBoundingBox Error: Bad shape detected");
1303 aShape = aCopyTool.Shape();
1305 // remove triangulation to obtain more exact boundaries
1306 BRepTools::Clean(aShape);
1308 BRepBndLib::Add(aShape, B);
1311 if (!GEOMUtils::PreciseBoundingBox(aShape, B)) {
1312 SetErrorCode("GetBoundingBox Error: Bounding box cannot be precised");
1317 B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
1319 catch (Standard_Failure& aFail) {
1320 SetErrorCode(aFail.GetMessageString());
1327 //=============================================================================
1331 //=============================================================================
1332 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
1333 (Handle(GEOM_Object) theShape,
1334 const Standard_Boolean precise)
1338 if (theShape.IsNull()) return NULL;
1340 //Add a new BoundingBox object
1341 Handle(GEOM_Object) aBnd = GetEngine()->AddObject(GEOM_BOX);
1343 //Add a new BoundingBox function
1344 const int aType = (precise ? BND_BOX_MEASURE_PRECISE : BND_BOX_MEASURE);
1345 Handle(GEOM_Function) aFunction =
1346 aBnd->AddFunction(GEOMImpl_MeasureDriver::GetID(), aType);
1347 if (aFunction.IsNull()) return NULL;
1349 //Check if the function is set correctly
1350 if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
1352 GEOMImpl_IMeasure aCI (aFunction);
1354 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1355 if (aRefShape.IsNull()) return NULL;
1357 aCI.SetBase(aRefShape);
1359 //Compute the BoundingBox value
1362 if (!GetSolver()->ComputeFunction(aFunction)) {
1363 SetErrorCode("Measure driver failed to compute a bounding box");
1367 catch (Standard_Failure& aFail) {
1368 SetErrorCode(aFail.GetMessageString());
1372 //Make a Python command
1373 GEOM::TPythonDump aPd(aFunction);
1375 aPd << aBnd << " = geompy.MakeBoundingBox(" << theShape;
1387 //=============================================================================
1391 //=============================================================================
1392 void GEOMImpl_IMeasureOperations::GetTolerance
1393 (Handle(GEOM_Object) theShape,
1394 Standard_Real& FaceMin, Standard_Real& FaceMax,
1395 Standard_Real& EdgeMin, Standard_Real& EdgeMax,
1396 Standard_Real& VertMin, Standard_Real& VertMax)
1400 if (theShape.IsNull()) return;
1402 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1403 if (aRefShape.IsNull()) return;
1405 TopoDS_Shape aShape = aRefShape->GetValue();
1406 if (aShape.IsNull()) {
1407 SetErrorCode("The Objects has NULL Shape");
1411 //Compute the parameters
1413 FaceMin = EdgeMin = VertMin = RealLast();
1414 FaceMax = EdgeMax = VertMax = -RealLast();
1418 for (TopExp_Explorer ExF (aShape, TopAbs_FACE); ExF.More(); ExF.Next()) {
1419 TopoDS_Face Face = TopoDS::Face(ExF.Current());
1420 T = BRep_Tool::Tolerance(Face);
1426 for (TopExp_Explorer ExE (aShape, TopAbs_EDGE); ExE.More(); ExE.Next()) {
1427 TopoDS_Edge Edge = TopoDS::Edge(ExE.Current());
1428 T = BRep_Tool::Tolerance(Edge);
1434 for (TopExp_Explorer ExV (aShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1435 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
1436 T = BRep_Tool::Tolerance(Vertex);
1443 catch (Standard_Failure& aFail) {
1444 SetErrorCode(aFail.GetMessageString());
1451 //=============================================================================
1455 //=============================================================================
1456 bool GEOMImpl_IMeasureOperations::CheckShape (Handle(GEOM_Object) theShape,
1457 const Standard_Boolean theIsCheckGeom,
1458 std::list<ShapeError> &theErrors)
1463 if (theShape.IsNull()) return false;
1465 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1466 if (aRefShape.IsNull()) return false;
1468 TopoDS_Shape aShape = aRefShape->GetValue();
1469 if (aShape.IsNull()) {
1470 SetErrorCode("The Objects has NULL Shape");
1474 //Compute the parameters
1475 bool isValid = false;
1478 BRepCheck_Analyzer ana (aShape, theIsCheckGeom);
1479 if (ana.IsValid()) {
1482 FillErrors(ana, aShape, theErrors);
1485 catch (Standard_Failure& aFail) {
1486 SetErrorCode(aFail.GetMessageString());
1494 //=============================================================================
1498 //=============================================================================
1499 TCollection_AsciiString GEOMImpl_IMeasureOperations::PrintShapeErrors
1500 (Handle(GEOM_Object) theShape,
1501 const std::list<ShapeError> &theErrors)
1503 TCollection_AsciiString aDump;
1505 if (theShape.IsNull()) {
1509 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1511 if (aRefShape.IsNull()) {
1515 TopoDS_Shape aShape = aRefShape->GetValue();
1517 if (aShape.IsNull()) {
1518 SetErrorCode("The Objects has NULL Shape");
1522 if (!theErrors.empty()) {
1523 // The shape is not valid. Prepare errors for dump.
1524 TopTools_IndexedMapOfShape anIndices;
1525 std::list<ShapeError>::const_iterator anIter = theErrors.begin();
1526 Standard_Integer nbv, nbe, nbw, nbf, nbs, nbo;
1527 nbv = nbe = nbw = nbf = nbs = nbo = 0;
1529 // Map sub-shapes and their indices
1530 TopExp::MapShapes(aShape, anIndices);
1532 const Standard_Integer aNbSubShapes = anIndices.Extent();
1533 TColStd_MapOfInteger aMapPbInd;
1535 aDump += " -- The Shape has problems :\n";
1536 aDump += " Check Count\n";
1537 aDump += " ------------------------------------------------\n";
1539 for (; anIter != theErrors.end(); anIter++) {
1540 Standard_Integer aNbShapes = anIter->incriminated.size();
1542 switch(anIter->error) {
1543 case BRepCheck_InvalidPointOnCurve:
1544 aDump += " Invalid Point on Curve ................... ";
1546 case BRepCheck_InvalidPointOnCurveOnSurface:
1547 aDump += " Invalid Point on CurveOnSurface .......... ";
1549 case BRepCheck_InvalidPointOnSurface:
1550 aDump += " Invalid Point on Surface ................. ";
1552 case BRepCheck_No3DCurve:
1553 aDump += " No 3D Curve .............................. ";
1555 case BRepCheck_Multiple3DCurve:
1556 aDump += " Multiple 3D Curve ........................ ";
1558 case BRepCheck_Invalid3DCurve:
1559 aDump += " Invalid 3D Curve ......................... ";
1561 case BRepCheck_NoCurveOnSurface:
1562 aDump += " No Curve on Surface ...................... ";
1564 case BRepCheck_InvalidCurveOnSurface:
1565 aDump += " Invalid Curve on Surface ................. ";
1567 case BRepCheck_InvalidCurveOnClosedSurface:
1568 aDump += " Invalid Curve on closed Surface .......... ";
1570 case BRepCheck_InvalidSameRangeFlag:
1571 aDump += " Invalid SameRange Flag ................... ";
1573 case BRepCheck_InvalidSameParameterFlag:
1574 aDump += " Invalid SameParameter Flag ............... ";
1576 case BRepCheck_InvalidDegeneratedFlag:
1577 aDump += " Invalid Degenerated Flag ................. ";
1579 case BRepCheck_FreeEdge:
1580 aDump += " Free Edge ................................ ";
1582 case BRepCheck_InvalidMultiConnexity:
1583 aDump += " Invalid MultiConnexity ................... ";
1585 case BRepCheck_InvalidRange:
1586 aDump += " Invalid Range ............................ ";
1588 case BRepCheck_EmptyWire:
1589 aDump += " Empty Wire ............................... ";
1591 case BRepCheck_RedundantEdge:
1592 aDump += " Redundant Edge ........................... ";
1594 case BRepCheck_SelfIntersectingWire:
1595 aDump += " Self Intersecting Wire ................... ";
1597 case BRepCheck_NoSurface:
1598 aDump += " No Surface ............................... ";
1600 case BRepCheck_InvalidWire:
1601 aDump += " Invalid Wire ............................. ";
1603 case BRepCheck_RedundantWire:
1604 aDump += " Redundant Wire ........................... ";
1606 case BRepCheck_IntersectingWires:
1607 aDump += " Intersecting Wires ....................... ";
1609 case BRepCheck_InvalidImbricationOfWires:
1610 aDump += " Invalid Imbrication of Wires ............. ";
1612 case BRepCheck_EmptyShell:
1613 aDump += " Empty Shell .............................. ";
1615 case BRepCheck_RedundantFace:
1616 aDump += " Redundant Face ........................... ";
1618 case BRepCheck_UnorientableShape:
1619 aDump += " Unorientable Shape ....................... ";
1621 case BRepCheck_NotClosed:
1622 aDump += " Not Closed ............................... ";
1624 case BRepCheck_NotConnected:
1625 aDump += " Not Connected ............................ ";
1627 case BRepCheck_SubshapeNotInShape:
1628 aDump += " Sub-shape not in Shape ................... ";
1630 case BRepCheck_BadOrientation:
1631 aDump += " Bad Orientation .......................... ";
1633 case BRepCheck_BadOrientationOfSubshape:
1634 aDump += " Bad Orientation of Sub-shape ............. ";
1636 case BRepCheck_InvalidToleranceValue:
1637 aDump += " Invalid Tolerance Value .................. ";
1639 case BRepCheck_CheckFail:
1640 aDump += " Check Shape Failure ...................... ";
1646 aDump += TCollection_AsciiString(aNbShapes) + "\n";
1648 // Count types of shape.
1649 std::list<int>::const_iterator aShIter = anIter->incriminated.begin();
1651 for (; aShIter != anIter->incriminated.end(); aShIter++) {
1652 const Standard_Integer anIndex = *aShIter;
1654 if (anIndex > 0 && anIndex <= aNbSubShapes && aMapPbInd.Add(anIndex)) {
1655 const TopoDS_Shape &aSubShape = anIndices.FindKey(anIndex);
1656 const TopAbs_ShapeEnum aType = aSubShape.ShapeType();
1659 case TopAbs_VERTEX : nbv++; break;
1660 case TopAbs_EDGE : nbe++; break;
1661 case TopAbs_WIRE : nbw++; break;
1662 case TopAbs_FACE : nbf++; break;
1663 case TopAbs_SHELL : nbs++; break;
1664 case TopAbs_SOLID : nbo++; break;
1671 const Standard_Integer aNbFaultyShapes = nbv + nbe + nbw + nbf + nbs + nbo;
1672 aDump += " ------------------------------------------------\n";
1673 aDump += "*** Shapes with problems : ";
1674 aDump += TCollection_AsciiString(aNbFaultyShapes) + "\n";
1677 aDump += "VERTEX : ";
1678 if (nbv < 10) aDump += " ";
1679 aDump += TCollection_AsciiString(nbv) + "\n";
1683 if (nbe < 10) aDump += " ";
1684 aDump += TCollection_AsciiString(nbe) + "\n";
1688 if (nbw < 10) aDump += " ";
1689 aDump += TCollection_AsciiString(nbw) + "\n";
1693 if (nbf < 10) aDump += " ";
1694 aDump += TCollection_AsciiString(nbf) + "\n";
1697 aDump += "SHELL : ";
1698 if (nbs < 10) aDump += " ";
1699 aDump += TCollection_AsciiString(nbs) + "\n";
1702 aDump += "SOLID : ";
1703 if (nbo < 10) aDump += " ";
1704 aDump += TCollection_AsciiString(nbo) + "\n";
1711 //=============================================================================
1713 * CheckSelfIntersections
1715 //=============================================================================
1716 bool GEOMImpl_IMeasureOperations::CheckSelfIntersections
1717 (Handle(GEOM_Object) theShape,
1718 const SICheckLevel theCheckLevel,
1719 Handle(TColStd_HSequenceOfInteger)& theIntersections)
1723 if (theIntersections.IsNull())
1724 theIntersections = new TColStd_HSequenceOfInteger;
1726 theIntersections->Clear();
1728 if (theShape.IsNull())
1731 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1732 if (aRefShape.IsNull()) return false;
1734 TopoDS_Shape aShape = aRefShape->GetValue();
1735 if (aShape.IsNull()) return false;
1738 TopoDS_Shape aScopy;
1740 GEOMAlgo_AlgoTools::CopyShape(aShape, aScopy);
1742 // Map sub-shapes and their indices
1743 TopTools_IndexedMapOfShape anIndices;
1744 TopExp::MapShapes(aScopy, anIndices);
1746 TopTools_ListOfShape aLCS;
1747 aLCS.Append(aScopy);
1749 BOPAlgo_CheckerSI aCSI; // checker of self-interferences
1750 aCSI.SetArguments(aLCS);
1751 aCSI.SetLevelOfCheck(theCheckLevel);
1753 // 1. Launch the checker
1755 Standard_Boolean iErr = aCSI.HasErrors();
1758 Standard_Integer aNbS, n1, n2;
1759 BOPDS_MapIteratorOfMapOfPair aItMPK;
1761 // 2. Take the shapes from DS
1762 const BOPDS_DS& aDS = aCSI.DS();
1763 aNbS=aDS.NbShapes();
1765 // 3. Get the pairs of interfered shapes
1766 const BOPDS_MapOfPair& aMPK=aDS.Interferences();
1767 aItMPK.Initialize(aMPK);
1768 for (; aItMPK.More(); aItMPK.Next()) {
1769 const BOPDS_Pair& aPK=aItMPK.Value();
1770 aPK.Indices(n1, n2);
1772 if (n1 > aNbS || n2 > aNbS){
1773 return false; // Error
1775 const TopoDS_Shape& aS1 = aDS.Shape(n1);
1776 const TopoDS_Shape& aS2 = aDS.Shape(n2);
1778 theIntersections->Append(anIndices.FindIndex(aS1));
1779 theIntersections->Append(anIndices.FindIndex(aS2));
1786 return theIntersections->IsEmpty();
1789 //=============================================================================
1791 * CheckSelfIntersectionsFast
1793 //=============================================================================
1794 bool GEOMImpl_IMeasureOperations::CheckSelfIntersectionsFast
1795 (Handle(GEOM_Object) theShape,
1796 float theDeflection, double theTolerance,
1797 Handle(TColStd_HSequenceOfInteger)& theIntersections)
1801 if (theIntersections.IsNull())
1802 theIntersections = new TColStd_HSequenceOfInteger;
1804 theIntersections->Clear();
1806 if (theShape.IsNull())
1809 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1810 if (aRefShape.IsNull()) return false;
1812 TopoDS_Shape aShape = aRefShape->GetValue();
1813 if (aShape.IsNull()) return false;
1816 TopoDS_Shape aScopy;
1818 GEOMAlgo_AlgoTools::CopyShape(aShape, aScopy);
1819 GEOMUtils::MeshShape(aScopy, theDeflection);
1821 // Map sub-shapes and their indices
1822 TopTools_IndexedMapOfShape anIndices;
1823 TopExp::MapShapes(aScopy, anIndices);
1825 // Checker of fast interferences
1826 BRepExtrema_SelfIntersection aTool(aScopy, (theTolerance <= 0.) ? 0.0 : theTolerance);
1828 // Launch the checker
1831 const BRepExtrema_MapOfIntegerPackedMapOfInteger& intersections = aTool.OverlapElements();
1833 std::set<Standard_Integer> processed;
1835 for (BRepExtrema_MapOfIntegerPackedMapOfInteger::Iterator it(intersections); it.More(); it.Next()) {
1836 Standard_Integer idxLeft = it.Key();
1837 if (processed.count(idxLeft) > 0) continue; // already added
1838 processed.insert(idxLeft);
1839 const TColStd_PackedMapOfInteger& overlaps = it.Value();
1840 for (TColStd_MapIteratorOfPackedMapOfInteger subit(overlaps); subit.More(); subit.Next()) {
1841 Standard_Integer idxRight = subit.Key();
1842 if (processed.count(idxRight) > 0) continue; // already added
1843 const TopoDS_Shape& aS1 = aTool.GetSubShape(idxLeft);
1844 const TopoDS_Shape& aS2 = aTool.GetSubShape(idxRight);
1845 theIntersections->Append(anIndices.FindIndex(aS1));
1846 theIntersections->Append(anIndices.FindIndex(aS2));
1853 return theIntersections->IsEmpty();
1856 //=============================================================================
1860 //=============================================================================
1861 bool GEOMImpl_IMeasureOperations::CheckBOPArguments
1862 (const Handle(GEOM_Object) &theShape)
1866 if (theShape.IsNull()) {
1870 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1872 if (aRefShape.IsNull()) {
1876 TopoDS_Shape aShape = aRefShape->GetValue();
1878 if (aShape.IsNull()) {
1882 //Compute the parameters
1883 bool isValid = GEOMUtils::CheckBOPArguments(aShape);
1890 //=============================================================================
1894 //=============================================================================
1895 bool GEOMImpl_IMeasureOperations::FastIntersect (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2,
1896 double theTolerance, float theDeflection,
1897 Handle(TColStd_HSequenceOfInteger)& theIntersections1,
1898 Handle(TColStd_HSequenceOfInteger)& theIntersections2)
1901 bool isGood = false;
1903 if (theIntersections1.IsNull())
1904 theIntersections1 = new TColStd_HSequenceOfInteger;
1906 theIntersections1->Clear();
1908 if (theIntersections2.IsNull())
1909 theIntersections2 = new TColStd_HSequenceOfInteger;
1911 theIntersections2->Clear();
1913 if (theShape1.IsNull() || theShape2.IsNull()) {
1914 SetErrorCode("Objects have NULL Shape");
1918 if (theShape1 == theShape2) {
1919 SetErrorCode("Objects are equal");
1922 Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction();
1923 Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction();
1924 if (aRefShape1.IsNull() || aRefShape2.IsNull()) return isGood;
1926 TopoDS_Shape aShape1 = aRefShape1->GetValue();
1927 TopoDS_Shape aShape2 = aRefShape2->GetValue();
1928 if (aShape1.IsNull() || aShape2.IsNull()) return isGood;
1931 TopoDS_Shape aScopy1, aScopy2;
1932 GEOMAlgo_AlgoTools::CopyShape(aShape1, aScopy1);
1933 GEOMAlgo_AlgoTools::CopyShape(aShape2, aScopy2);
1935 GEOMUtils::MeshShape(aScopy1, theDeflection);
1936 GEOMUtils::MeshShape(aScopy2, theDeflection);
1938 // Map sub-shapes and their indices
1939 TopTools_IndexedMapOfShape anIndices1, anIndices2;
1940 TopExp::MapShapes(aScopy1, anIndices1);
1941 TopExp::MapShapes(aScopy2, anIndices2);
1943 TopTools_ListOfShape aLCS1, aLCS2;
1944 aLCS1.Append(aScopy1); aLCS2.Append(aScopy2);
1946 BRepExtrema_ShapeProximity aBSP; // checker of fast interferences
1947 aBSP.LoadShape1(aScopy1); aBSP.LoadShape2(aScopy2);
1948 aBSP.SetTolerance((theTolerance <= 0.) ? 0.0 : theTolerance);
1950 // 1. Launch the checker
1953 // 2. Get sets of IDs of overlapped faces
1954 for (BRepExtrema_MapOfIntegerPackedMapOfInteger::Iterator anIt1 (aBSP.OverlapSubShapes1()); anIt1.More(); anIt1.Next())
1956 const TopoDS_Shape& aS1 = aBSP.GetSubShape1(anIt1.Key());
1957 theIntersections1->Append(anIndices1.FindIndex(aS1));
1960 for (BRepExtrema_MapOfIntegerPackedMapOfInteger::Iterator anIt2 (aBSP.OverlapSubShapes2()); anIt2.More(); anIt2.Next())
1962 const TopoDS_Shape& aS2 = aBSP.GetSubShape2(anIt2.Key());
1963 theIntersections2->Append(anIndices2.FindIndex(aS2));
1966 isGood = !theIntersections1->IsEmpty() && !theIntersections1->IsEmpty();
1974 //=============================================================================
1978 //=============================================================================
1979 TCollection_AsciiString GEOMImpl_IMeasureOperations::IsGoodForSolid (Handle(GEOM_Object) theShape)
1983 TCollection_AsciiString aRes = "";
1985 if (theShape.IsNull()) {
1986 aRes = "WRN_NULL_OBJECT_OR_SHAPE";
1989 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1990 if (aRefShape.IsNull()) {
1991 aRes = "WRN_NULL_OBJECT_OR_SHAPE";
1994 TopoDS_Shape aShape = aRefShape->GetValue();
1995 if (aShape.IsNull()) {
1996 aRes = "WRN_NULL_OBJECT_OR_SHAPE";
1999 if (aShape.ShapeType() == TopAbs_COMPOUND) {
2000 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
2001 if (It.More()) aShape = It.Value();
2003 if (aShape.ShapeType() == TopAbs_SHELL) {
2004 BRepCheck_Shell chkShell (TopoDS::Shell(aShape));
2005 if (chkShell.Closed() == BRepCheck_NotClosed) {
2006 aRes = "WRN_SHAPE_UNCLOSED";
2010 aRes = "WRN_SHAPE_NOT_SHELL";
2022 //=============================================================================
2026 //=============================================================================
2027 TCollection_AsciiString GEOMImpl_IMeasureOperations::WhatIs (Handle(GEOM_Object) theShape)
2031 TCollection_AsciiString Astr;
2033 if (theShape.IsNull()) return Astr;
2035 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
2036 if (aRefShape.IsNull()) return Astr;
2038 TopoDS_Shape aShape = aRefShape->GetValue();
2039 if (aShape.IsNull()) {
2040 SetErrorCode("The Objects has NULL Shape");
2044 //Compute the parameters
2045 if (aShape.ShapeType() == TopAbs_EDGE) {
2046 if (BRep_Tool::Degenerated(TopoDS::Edge(aShape))) {
2047 Astr = Astr + " It is a degenerated edge \n";
2051 Astr = Astr + " Number of sub-shapes : \n";
2055 int iType, nbTypes [TopAbs_SHAPE], nbFlatType [TopAbs_SHAPE];
2056 for (iType = 0; iType < TopAbs_SHAPE; ++iType) {
2058 nbFlatType[iType] = 0;
2060 nbTypes[aShape.ShapeType()]++;
2062 TopTools_MapOfShape aMapOfShape;
2063 aMapOfShape.Add(aShape);
2064 TopTools_ListOfShape aListOfShape;
2065 aListOfShape.Append(aShape);
2067 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
2068 for (; itL.More(); itL.Next()) {
2069 TopoDS_Shape sp = itL.Value();
2070 TopoDS_Iterator it (sp);
2071 for (; it.More(); it.Next()) {
2072 TopoDS_Shape s = it.Value();
2073 if (aMapOfShape.Add(s)) {
2074 aListOfShape.Append(s);
2075 nbTypes[s.ShapeType()]++;
2076 if ((sp.ShapeType() == TopAbs_COMPOUND) || (sp.ShapeType() == TopAbs_COMPSOLID)) {
2077 nbFlatType[s.ShapeType()]++;
2083 Astr = Astr + " VERTEX : " + TCollection_AsciiString(nbTypes[TopAbs_VERTEX]) + "\n";
2084 Astr = Astr + " EDGE : " + TCollection_AsciiString(nbTypes[TopAbs_EDGE]) + "\n";
2085 Astr = Astr + " WIRE : " + TCollection_AsciiString(nbTypes[TopAbs_WIRE]) + "\n";
2086 Astr = Astr + " FACE : " + TCollection_AsciiString(nbTypes[TopAbs_FACE]) + "\n";
2087 Astr = Astr + " SHELL : " + TCollection_AsciiString(nbTypes[TopAbs_SHELL]) + "\n";
2088 Astr = Astr + " SOLID : " + TCollection_AsciiString(nbTypes[TopAbs_SOLID]) + "\n";
2089 Astr = Astr + " COMPSOLID : " + TCollection_AsciiString(nbTypes[TopAbs_COMPSOLID]) + "\n";
2090 Astr = Astr + " COMPOUND : " + TCollection_AsciiString(nbTypes[TopAbs_COMPOUND]) + "\n";
2091 Astr = Astr + " SHAPE : " + TCollection_AsciiString(aMapOfShape.Extent()) + "\n";
2093 if ((aShape.ShapeType() == TopAbs_COMPOUND) || (aShape.ShapeType() == TopAbs_COMPSOLID)){
2094 Astr = Astr + " --------------------- \n Flat content : \n";
2095 if (nbFlatType[TopAbs_VERTEX] > 0)
2096 Astr = Astr + " VERTEX : " + TCollection_AsciiString(nbFlatType[TopAbs_VERTEX]) + "\n";
2097 if (nbFlatType[TopAbs_EDGE] > 0)
2098 Astr = Astr + " EDGE : " + TCollection_AsciiString(nbFlatType[TopAbs_EDGE]) + "\n";
2099 if (nbFlatType[TopAbs_WIRE] > 0)
2100 Astr = Astr + " WIRE : " + TCollection_AsciiString(nbFlatType[TopAbs_WIRE]) + "\n";
2101 if (nbFlatType[TopAbs_FACE] > 0)
2102 Astr = Astr + " FACE : " + TCollection_AsciiString(nbFlatType[TopAbs_FACE]) + "\n";
2103 if (nbFlatType[TopAbs_SHELL] > 0)
2104 Astr = Astr + " SHELL : " + TCollection_AsciiString(nbFlatType[TopAbs_SHELL]) + "\n";
2105 if (nbFlatType[TopAbs_SOLID] > 0)
2106 Astr = Astr + " SOLID : " + TCollection_AsciiString(nbFlatType[TopAbs_SOLID]) + "\n";
2109 catch (Standard_Failure& aFail) {
2110 SetErrorCode(aFail.GetMessageString());
2118 //=============================================================================
2122 //=============================================================================
2124 GEOMImpl_IMeasureOperations::AreCoordsInside(Handle(GEOM_Object) theShape,
2125 const std::vector<double>& coords,
2128 std::vector<bool> isInsideRes;
2129 if (!theShape.IsNull()) {
2130 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
2131 if (!aRefShape.IsNull()) {
2132 TopoDS_Shape aShape = aRefShape->GetValue();
2133 if (!aShape.IsNull())
2135 TopTools_IndexedMapOfShape mapShape;
2137 TopExp_Explorer anExp;
2138 for ( anExp.Init( aShape, TopAbs_SOLID ); anExp.More(); anExp.Next() )
2139 mapShape.Add( anExp.Current() );
2140 for ( anExp.Init( aShape, TopAbs_FACE, TopAbs_SOLID ); anExp.More(); anExp.Next() )
2141 mapShape.Add( anExp.Current() );
2142 for ( anExp.Init( aShape, TopAbs_EDGE, TopAbs_FACE ); anExp.More(); anExp.Next() )
2143 mapShape.Add( anExp.Current() );
2144 for ( anExp.Init( aShape, TopAbs_VERTEX, TopAbs_EDGE ); anExp.More(); anExp.Next() )
2145 mapShape.Add( anExp.Current() ); //// ?????????
2147 size_t nb_points = coords.size()/3, nb_points_inside = 0;
2148 isInsideRes.resize( nb_points, false );
2150 for ( int iS = 1; iS <= mapShape.Extent(); ++iS )
2152 if ( nb_points_inside == nb_points )
2154 aShape = mapShape( iS );
2155 switch ( aShape.ShapeType() ) {
2158 BRepClass3d_SolidClassifier SC( TopoDS::Solid( aShape ));
2159 for ( size_t i = 0; i < nb_points; i++)
2161 if ( isInsideRes[ i ]) continue;
2162 gp_Pnt aPnt( coords[3*i], coords[3*i+1], coords[3*i+2] );
2163 SC.Perform( aPnt, tolerance );
2164 isInsideRes[ i ] = (( SC.State() == TopAbs_IN ) || ( SC.State() == TopAbs_ON ));
2165 nb_points_inside += isInsideRes[ i ];
2171 Standard_Real u1,u2,v1,v2;
2172 const TopoDS_Face& face = TopoDS::Face( aShape );
2173 Handle(Geom_Surface) surf = BRep_Tool::Surface( face );
2174 surf->Bounds( u1,u2,v1,v2 );
2175 GeomAPI_ProjectPointOnSurf project;
2176 project.Init(surf, u1,u2, v1,v2, tolerance );
2177 for ( size_t i = 0; i < nb_points; i++)
2179 if ( isInsideRes[ i ]) continue;
2180 gp_Pnt aPnt( coords[3*i], coords[3*i+1], coords[3*i+2] );
2181 project.Perform( aPnt );
2182 if ( project.IsDone() &&
2183 project.NbPoints() > 0 &&
2184 project.LowerDistance() <= tolerance )
2187 project.LowerDistanceParameters(u, v);
2188 gp_Pnt2d uv( u, v );
2189 BRepClass_FaceClassifier FC ( face, uv, tolerance );
2190 isInsideRes[ i ] = (( FC.State() == TopAbs_IN ) || ( FC.State() == TopAbs_ON ));
2191 nb_points_inside += isInsideRes[ i ];
2199 const TopoDS_Edge& edge = TopoDS::Edge( aShape );
2200 Handle(Geom_Curve) curve = BRep_Tool::Curve( edge, f, l );
2201 GeomAPI_ProjectPointOnCurve project;
2202 project.Init( curve, f, l );
2203 for ( size_t i = 0; i < nb_points; i++)
2205 if ( isInsideRes[ i ]) continue;
2206 gp_Pnt aPnt( coords[3*i], coords[3*i+1], coords[3*i+2] );
2207 project.Perform( aPnt );
2208 isInsideRes[ i ] = ( project.NbPoints() > 0 &&
2209 project.LowerDistance() <= tolerance );
2210 nb_points_inside += isInsideRes[ i ];
2216 gp_Pnt aVPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ));
2217 for ( size_t i = 0; i < nb_points; i++)
2219 if ( isInsideRes[ i ]) continue;
2220 gp_Pnt aPnt( coords[3*i], coords[3*i+1], coords[3*i+2] );
2221 isInsideRes[ i ] = ( aPnt.SquareDistance( aVPnt ) <= tolerance * tolerance );
2222 nb_points_inside += isInsideRes[ i ];
2227 } // switch ( aShape.ShapeType() )
2235 //=============================================================================
2239 //=============================================================================
2241 GEOMImpl_IMeasureOperations::GetMinDistance (Handle(GEOM_Object) theShape1,
2242 Handle(GEOM_Object) theShape2,
2251 Standard_Real MinDist = 1.e9;
2253 if (theShape1.IsNull() || theShape2.IsNull()) return MinDist;
2255 Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction();
2256 Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction();
2257 if (aRefShape1.IsNull() || aRefShape2.IsNull()) return MinDist;
2259 TopoDS_Shape aShape1 = aRefShape1->GetValue();
2260 TopoDS_Shape aShape2 = aRefShape2->GetValue();
2261 if (aShape1.IsNull() || aShape2.IsNull()) {
2262 SetErrorCode("One of Objects has NULL Shape");
2266 //Compute the parameters
2270 gp_Pnt aPnt1, aPnt2;
2272 MinDist = GEOMUtils::GetMinDistance(aShape1, aShape2, aPnt1, aPnt2);
2274 if (MinDist >= 0.0) {
2275 aPnt1.Coord(X1, Y1, Z1);
2276 aPnt2.Coord(X2, Y2, Z2);
2281 catch (Standard_Failure& aFail) {
2282 SetErrorCode(aFail.GetMessageString());
2290 //=======================================================================
2292 * Get coordinates of closest points of two shapes
2294 //=======================================================================
2295 Standard_Integer GEOMImpl_IMeasureOperations::ClosestPoints (Handle(GEOM_Object) theShape1,
2296 Handle(GEOM_Object) theShape2,
2297 Handle(TColStd_HSequenceOfReal)& theDoubles)
2300 Standard_Integer nbSolutions = 0;
2302 if (theShape1.IsNull() || theShape2.IsNull()) return nbSolutions;
2304 Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction();
2305 Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction();
2306 if (aRefShape1.IsNull() || aRefShape2.IsNull()) return nbSolutions;
2308 TopoDS_Shape aShape1 = aRefShape1->GetValue();
2309 TopoDS_Shape aShape2 = aRefShape2->GetValue();
2310 if (aShape1.IsNull() || aShape2.IsNull()) {
2311 SetErrorCode("One of Objects has NULL Shape");
2315 // Compute the extremities
2320 // additional workaround for bugs 19899, 19908 and 19910 from Mantis
2322 double dist = GEOMUtils::GetMinDistanceSingular(aShape1, aShape2, P1s, P2s);
2323 bool singularBetter = dist >= 0;
2325 BRepExtrema_DistShapeShape dst (aShape1, aShape2);
2327 nbSolutions = dst.NbSolution();
2328 if (theDoubles.IsNull()) theDoubles = new TColStd_HSequenceOfReal;
2331 for (int i = 1; i <= nbSolutions; i++) {
2332 P1 = dst.PointOnShape1(i);
2333 P2 = dst.PointOnShape2(i);
2335 theDoubles->Append(P1.X());
2336 theDoubles->Append(P1.Y());
2337 theDoubles->Append(P1.Z());
2338 theDoubles->Append(P2.X());
2339 theDoubles->Append(P2.Y());
2340 theDoubles->Append(P2.Z());
2342 Standard_Real Dist = P1.Distance(P2);
2343 singularBetter = singularBetter && dist < Dist;
2347 if (singularBetter) {
2348 if (theDoubles.IsNull()) theDoubles = new TColStd_HSequenceOfReal;
2349 else theDoubles->Clear();
2353 theDoubles->Append(P1s.X());
2354 theDoubles->Append(P1s.Y());
2355 theDoubles->Append(P1s.Z());
2356 theDoubles->Append(P2s.X());
2357 theDoubles->Append(P2s.Y());
2358 theDoubles->Append(P2s.Z());
2361 catch (Standard_Failure& aFail) {
2362 SetErrorCode(aFail.GetMessageString());
2370 //=======================================================================
2372 * Get coordinates of point
2374 //=======================================================================
2375 void GEOMImpl_IMeasureOperations::PointCoordinates (Handle(GEOM_Object) theShape,
2376 Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ)
2380 if (theShape.IsNull())
2383 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
2384 if (aRefShape.IsNull())
2387 TopoDS_Shape aShape = aRefShape->GetValue();
2388 if (aShape.IsNull() || aShape.ShapeType() != TopAbs_VERTEX)
2390 SetErrorCode( "Shape must be a vertex" );
2396 gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
2403 catch (Standard_Failure& aFail)
2405 SetErrorCode( aFail.GetMessageString() );
2409 //=======================================================================
2411 * Compute angle (in degrees) between two lines
2413 //=======================================================================
2414 Standard_Real GEOMImpl_IMeasureOperations::GetAngle (Handle(GEOM_Object) theLine1,
2415 Handle(GEOM_Object) theLine2)
2417 if (theLine1->GetType() == GEOM_VECTOR &&
2418 theLine2->GetType() == GEOM_VECTOR)
2419 return GetAngleBtwVectors(theLine1, theLine2);
2423 Standard_Real anAngle = -1.0;
2425 if (theLine1.IsNull() || theLine2.IsNull())
2428 Handle(GEOM_Function) aRefLine1 = theLine1->GetLastFunction();
2429 Handle(GEOM_Function) aRefLine2 = theLine2->GetLastFunction();
2430 if (aRefLine1.IsNull() || aRefLine2.IsNull())
2433 TopoDS_Shape aLine1 = aRefLine1->GetValue();
2434 TopoDS_Shape aLine2 = aRefLine2->GetValue();
2435 if (aLine1.IsNull() || aLine2.IsNull() ||
2436 aLine1.ShapeType() != TopAbs_EDGE ||
2437 aLine2.ShapeType() != TopAbs_EDGE)
2439 SetErrorCode("Two edges must be given");
2445 TopoDS_Edge E1 = TopoDS::Edge(aLine1);
2446 TopoDS_Edge E2 = TopoDS::Edge(aLine2);
2449 Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
2450 Handle(Geom_Curve) C2 = BRep_Tool::Curve(E2,fp,lp);
2452 if ( C1.IsNull() || C2.IsNull() ||
2453 !C1->IsKind(STANDARD_TYPE(Geom_Line)) ||
2454 !C2->IsKind(STANDARD_TYPE(Geom_Line)))
2456 SetErrorCode("The edges must be linear");
2460 Handle(Geom_Line) L1 = Handle(Geom_Line)::DownCast(C1);
2461 Handle(Geom_Line) L2 = Handle(Geom_Line)::DownCast(C2);
2463 gp_Lin aLin1 = L1->Lin();
2464 gp_Lin aLin2 = L2->Lin();
2466 anAngle = aLin1.Angle(aLin2);
2467 anAngle *= 180. / M_PI; // convert radians into degrees
2469 if (anAngle > 90.0) {
2470 anAngle = 180.0 - anAngle;
2475 catch (Standard_Failure& aFail)
2477 SetErrorCode(aFail.GetMessageString());
2483 //=======================================================================
2485 * Compute angle (in degrees) between two vectors
2487 //=======================================================================
2488 Standard_Real GEOMImpl_IMeasureOperations::GetAngleBtwVectors (Handle(GEOM_Object) theVec1,
2489 Handle(GEOM_Object) theVec2)
2493 Standard_Real anAngle = -1.0;
2495 if (theVec1.IsNull() || theVec2.IsNull())
2498 if (theVec1->GetType() != GEOM_VECTOR || theVec2->GetType() != GEOM_VECTOR) {
2499 SetErrorCode("Two vectors must be given");
2503 Handle(GEOM_Function) aRefVec1 = theVec1->GetLastFunction();
2504 Handle(GEOM_Function) aRefVec2 = theVec2->GetLastFunction();
2505 if (aRefVec1.IsNull() || aRefVec2.IsNull())
2508 TopoDS_Shape aVec1 = aRefVec1->GetValue();
2509 TopoDS_Shape aVec2 = aRefVec2->GetValue();
2510 if (aVec1.IsNull() || aVec2.IsNull() ||
2511 aVec1.ShapeType() != TopAbs_EDGE ||
2512 aVec2.ShapeType() != TopAbs_EDGE)
2514 SetErrorCode("Two edges must be given");
2520 TopoDS_Edge aE1 = TopoDS::Edge(aVec1);
2521 TopoDS_Edge aE2 = TopoDS::Edge(aVec2);
2523 TopoDS_Vertex aP11, aP12, aP21, aP22;
2524 TopExp::Vertices(aE1, aP11, aP12, Standard_True);
2525 TopExp::Vertices(aE2, aP21, aP22, Standard_True);
2526 if (aP11.IsNull() || aP12.IsNull() || aP21.IsNull() || aP22.IsNull()) {
2527 SetErrorCode("Bad edge given");
2531 gp_Vec aV1 (BRep_Tool::Pnt(aP11), BRep_Tool::Pnt(aP12));
2532 gp_Vec aV2 (BRep_Tool::Pnt(aP21), BRep_Tool::Pnt(aP22)) ;
2534 anAngle = aV1.Angle(aV2);
2535 anAngle *= 180. / M_PI; // convert radians into degrees
2539 catch (Standard_Failure& aFail)
2541 SetErrorCode(aFail.GetMessageString());
2548 //=============================================================================
2552 //=============================================================================
2553 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IMeasureOperations::PatchFace(Handle(GEOM_Object) theShape)
2557 if (theShape.IsNull()) return NULL;
2559 Handle(GEOM_Object) aPatchFace = GetEngine()->AddObject(GEOM_PATCH_FACE);
2560 Handle(GEOM_Function) aFunction = aPatchFace->AddFunction(GEOMImpl_PatchFaceDriver::GetID(), 1);
2561 if (aFunction.IsNull()) return NULL;
2563 //Check if the function is set correctly
2564 if (aFunction->GetDriverGUID() != GEOMImpl_PatchFaceDriver::GetID()) return NULL;
2566 GEOMImpl_IPatchFace aPI(aFunction);
2567 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
2568 if (aRefShape.IsNull()) return NULL;
2570 aPI.SetShape(aRefShape);
2571 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2577 if (!GetSolver()->ComputeFunction(aFunction))
2579 SetErrorCode("patch face driver failed");
2583 // Get result compound and collect all faces into result sequence
2584 TopoDS_Shape aResCompound = aFunction->GetValue();
2585 TopTools_IndexedMapOfShape anIndices;
2586 TopExp::MapShapes(aResCompound, anIndices);
2588 Handle(TColStd_HArray1OfInteger) anArray;
2589 for (TopExp_Explorer anExpW(aResCompound, TopAbs_FACE); anExpW.More(); anExpW.Next())
2591 TopoDS_Shape aValue = anExpW.Value();
2592 anArray = new TColStd_HArray1OfInteger(1, 1);
2593 anArray->SetValue(1, anIndices.FindIndex(aValue));
2595 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(aPatchFace, anArray);
2596 if (!anObj.IsNull())
2598 aSeq->Append(anObj);
2602 catch (Standard_Failure& aFail)
2604 SetErrorCode(aFail.GetMessageString());
2608 //Make a Python command
2609 GEOM::TPythonDump(aFunction, true)
2610 << "[" << aSeq << "] = geompy.PatchFace(" << theShape << ")";
2616 //=============================================================================
2618 * CurveCurvatureByParam
2620 //=============================================================================
2621 Standard_Real GEOMImpl_IMeasureOperations::CurveCurvatureByParam
2622 (Handle(GEOM_Object) theCurve, Standard_Real& theParam)
2625 Standard_Real aRes = -1.0;
2627 if(theCurve.IsNull()) return aRes;
2629 Handle(GEOM_Function) aRefShape = theCurve->GetLastFunction();
2630 if(aRefShape.IsNull()) return aRes;
2632 TopoDS_Shape aShape = aRefShape->GetValue();
2633 if(aShape.IsNull()) {
2634 SetErrorCode("One of Objects has NULL Shape");
2638 Standard_Real aFP, aLP, aP;
2639 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aShape), aFP, aLP);
2640 aP = aFP + (aLP - aFP) * theParam;
2642 if(aCurve.IsNull()) return aRes;
2647 GeomLProp_CLProps Prop = GeomLProp_CLProps
2648 (aCurve, aP, 2, Precision::Confusion());
2649 aRes = fabs(Prop.Curvature());
2652 catch (Standard_Failure& aFail) {
2653 SetErrorCode(aFail.GetMessageString());
2657 if( aRes > Precision::Confusion() )
2666 //=============================================================================
2668 * CurveCurvatureByPoint
2670 //=============================================================================
2671 Standard_Real GEOMImpl_IMeasureOperations::CurveCurvatureByPoint
2672 (Handle(GEOM_Object) theCurve, Handle(GEOM_Object) thePoint)
2675 Standard_Real aRes = -1.0;
2677 if( theCurve.IsNull() || thePoint.IsNull() ) return aRes;
2679 Handle(GEOM_Function) aRefCurve = theCurve->GetLastFunction();
2680 Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction();
2681 if( aRefCurve.IsNull() || aRefPoint.IsNull() ) return aRes;
2683 TopoDS_Edge anEdge = TopoDS::Edge(aRefCurve->GetValue());
2684 TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue());
2685 if( anEdge.IsNull() || aPnt.IsNull() ) {
2686 SetErrorCode("One of Objects has NULL Shape");
2690 Standard_Real aFP, aLP;
2691 Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFP, aLP);
2692 if(aCurve.IsNull()) return aRes;
2693 gp_Pnt aPoint = BRep_Tool::Pnt(aPnt);
2698 GeomAPI_ProjectPointOnCurve PPCurve(aPoint, aCurve, aFP, aLP);
2699 if(PPCurve.NbPoints()>0) {
2700 GeomLProp_CLProps Prop = GeomLProp_CLProps
2701 (aCurve, PPCurve.LowerDistanceParameter(), 2, Precision::Confusion());
2702 aRes = fabs(Prop.Curvature());
2706 catch (Standard_Failure& aFail) {
2707 SetErrorCode(aFail.GetMessageString());
2711 if( aRes > Precision::Confusion() )
2720 //=============================================================================
2722 * getSurfaceCurvatures
2724 //=============================================================================
2725 Standard_Real GEOMImpl_IMeasureOperations::getSurfaceCurvatures
2726 (const Handle(Geom_Surface)& aSurf,
2727 Standard_Real theUParam,
2728 Standard_Real theVParam,
2729 Standard_Boolean theNeedMaxCurv)
2732 Standard_Real aRes = 1.0;
2734 if (aSurf.IsNull()) return aRes;
2738 GeomLProp_SLProps Prop = GeomLProp_SLProps
2739 (aSurf, theUParam, theVParam, 2, Precision::Confusion());
2740 if(Prop.IsCurvatureDefined()) {
2741 if(Prop.IsUmbilic()) {
2742 //cout<<"is umbilic"<<endl;
2743 aRes = fabs(Prop.MeanCurvature());
2746 //cout<<"is not umbilic"<<endl;
2747 double c1 = fabs(Prop.MaxCurvature());
2748 double c2 = fabs(Prop.MinCurvature());
2757 catch (Standard_Failure& aFail) {
2758 SetErrorCode(aFail.GetMessageString());
2762 if( fabs(aRes) > Precision::Confusion() )
2771 //=============================================================================
2773 * MaxSurfaceCurvatureByParam
2775 //=============================================================================
2776 Standard_Real GEOMImpl_IMeasureOperations::MaxSurfaceCurvatureByParam
2777 (Handle(GEOM_Object) theSurf,
2778 Standard_Real& theUParam,
2779 Standard_Real& theVParam)
2782 Standard_Real aRes = -1.0;
2784 if (theSurf.IsNull()) return aRes;
2786 Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
2787 if(aRefShape.IsNull()) return aRes;
2789 TopoDS_Shape aShape = aRefShape->GetValue();
2790 if(aShape.IsNull()) {
2791 SetErrorCode("One of Objects has NULL Shape");
2795 TopoDS_Face F = TopoDS::Face(aShape);
2796 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
2798 //Compute the parameters
2799 Standard_Real U1,U2,V1,V2;
2800 ShapeAnalysis::GetFaceUVBounds(F,U1,U2,V1,V2);
2801 Standard_Real U = U1 + (U2-U1)*theUParam;
2802 Standard_Real V = V1 + (V2-V1)*theVParam;
2804 return getSurfaceCurvatures(aSurf, U, V, true);
2808 //=============================================================================
2810 * MaxSurfaceCurvatureByPoint
2812 //=============================================================================
2813 Standard_Real GEOMImpl_IMeasureOperations::MaxSurfaceCurvatureByPoint
2814 (Handle(GEOM_Object) theSurf, Handle(GEOM_Object) thePoint)
2817 Standard_Real aRes = -1.0;
2819 if( theSurf.IsNull() || thePoint.IsNull() ) return aRes;
2821 Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
2822 Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction();
2823 if( aRefShape.IsNull() || aRefPoint.IsNull() ) return aRes;
2825 TopoDS_Face aFace = TopoDS::Face(aRefShape->GetValue());
2826 TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue());
2827 if( aFace.IsNull() || aPnt.IsNull() ) {
2828 SetErrorCode("One of Objects has NULL Shape");
2832 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
2833 if(aSurf.IsNull()) return aRes;
2834 gp_Pnt aPoint = BRep_Tool::Pnt(aPnt);
2836 //Compute the parameters
2837 ShapeAnalysis_Surface sas(aSurf);
2838 gp_Pnt2d UV = sas.ValueOfUV(aPoint,Precision::Confusion());
2840 return getSurfaceCurvatures(aSurf, UV.X(), UV.Y(), true);
2844 //=============================================================================
2846 * MinSurfaceCurvatureByParam
2848 //=============================================================================
2849 Standard_Real GEOMImpl_IMeasureOperations::MinSurfaceCurvatureByParam
2850 (Handle(GEOM_Object) theSurf,
2851 Standard_Real& theUParam,
2852 Standard_Real& theVParam)
2855 Standard_Real aRes = -1.0;
2857 if (theSurf.IsNull()) return aRes;
2859 Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
2860 if(aRefShape.IsNull()) return aRes;
2862 TopoDS_Shape aShape = aRefShape->GetValue();
2863 if(aShape.IsNull()) {
2864 SetErrorCode("One of Objects has NULL Shape");
2868 TopoDS_Face F = TopoDS::Face(aShape);
2869 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
2871 //Compute the parameters
2872 Standard_Real U1,U2,V1,V2;
2873 ShapeAnalysis::GetFaceUVBounds(F,U1,U2,V1,V2);
2874 Standard_Real U = U1 + (U2-U1)*theUParam;
2875 Standard_Real V = V1 + (V2-V1)*theVParam;
2877 return getSurfaceCurvatures(aSurf, U, V, false);
2881 //=============================================================================
2883 * MinSurfaceCurvatureByPoint
2885 //=============================================================================
2886 Standard_Real GEOMImpl_IMeasureOperations::MinSurfaceCurvatureByPoint
2887 (Handle(GEOM_Object) theSurf, Handle(GEOM_Object) thePoint)
2890 Standard_Real aRes = -1.0;
2892 if( theSurf.IsNull() || thePoint.IsNull() ) return aRes;
2894 Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
2895 Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction();
2896 if( aRefShape.IsNull() || aRefPoint.IsNull() ) return aRes;
2898 TopoDS_Face aFace = TopoDS::Face(aRefShape->GetValue());
2899 TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue());
2900 if( aFace.IsNull() || aPnt.IsNull() ) {
2901 SetErrorCode("One of Objects has NULL Shape");
2905 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
2906 if(aSurf.IsNull()) return aRes;
2907 gp_Pnt aPoint = BRep_Tool::Pnt(aPnt);
2909 //Compute the parameters
2910 ShapeAnalysis_Surface sas(aSurf);
2911 gp_Pnt2d UV = sas.ValueOfUV(aPoint,Precision::Confusion());
2913 return getSurfaceCurvatures(aSurf, UV.X(), UV.Y(), false);
2916 //=============================================================================
2918 * SurfaceCurvatureByPointAndDirection
2920 //=============================================================================
2921 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::SurfaceCurvatureByPointAndDirection
2922 (Handle(GEOM_Object) theSurf,
2923 Handle(GEOM_Object) thePoint,
2924 Handle(GEOM_Object) theDirection)
2928 if (theSurf.IsNull() || thePoint.IsNull() || theDirection.IsNull()) return NULL;
2930 Handle(GEOM_Function) aSurf = theSurf->GetLastFunction();
2931 Handle(GEOM_Function) aPoint = thePoint->GetLastFunction();
2932 Handle(GEOM_Function) aDirection = theDirection->GetLastFunction();
2933 if (aSurf.IsNull() || aPoint.IsNull() || aDirection.IsNull()) return NULL;
2935 //Add a new CurvatureVector object
2936 //Handle(GEOM_Object) aCV = GetEngine()->AddObject(GEOM_CURVATURE_VEC);
2937 Handle(GEOM_Object) aCV = GetEngine()->AddObject(GEOM_VECTOR);
2939 //Add a new CurvatureVector function
2940 Handle(GEOM_Function) aFunction =
2941 aCV->AddFunction(GEOMImpl_MeasureDriver::GetID(), CURVATURE_VEC_MEASURE);
2942 if (aFunction.IsNull()) return NULL;
2944 //Check if the function is set correctly
2945 if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
2947 GEOMImpl_IMeasure aCI (aFunction);
2949 aCI.SetPoint(aPoint);
2950 aCI.SetDirection(aDirection);
2952 //Compute the CurvatureVector
2955 if (!GetSolver()->ComputeFunction(aFunction)) {
2956 SetErrorCode("Measure driver failed to compute a surface curvature");
2960 catch (Standard_Failure& aFail) {
2961 SetErrorCode(aFail.GetMessageString());
2965 //Make a Python command
2966 GEOM::TPythonDump(aFunction) << aCV << " = geompy.CurvatureOnFace(" << theSurf
2967 << ", " << thePoint << ", " << theDirection << ")";
2973 //=============================================================================
2977 //=============================================================================
2978 Handle(TColStd_HArray1OfReal) GEOMImpl_IMeasureOperations::XYZtoUV
2979 (Handle(GEOM_Object) theSurf,
2980 const Handle(TColStd_HArray1OfReal)& theXYZlist,
2985 Handle(TColStd_HArray1OfReal) aRet;
2987 // Check list of coordinates
2988 int nbC = theXYZlist->Length();
2990 if (nbP * 3 != nbC) {
2991 SetErrorCode("Coordinates list length is not divisible by 3");
2996 if (theSurf.IsNull()) {
2997 SetErrorCode("The shape is NULL");
3001 Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
3002 if (aRefShape.IsNull()) {
3003 SetErrorCode("The shape is NULL");
3007 TopoDS_Shape aShape = aRefShape->GetValue();
3008 if (aShape.IsNull()) {
3009 SetErrorCode("The shape is NULL");
3013 // The shape can be a face, a shell of one face or a compound with one face
3015 if (aShape.ShapeType() == TopAbs_FACE) {
3016 F = TopoDS::Face(aShape);
3018 else if (aShape.ShapeType() < TopAbs_FACE) {
3019 TopExp_Explorer Exp (aShape, TopAbs_FACE);
3021 F = TopoDS::Face(Exp.Current());
3024 SetErrorCode("There should be only one face");
3030 SetErrorCode("There are no faces");
3035 Standard_Real aTol = BRep_Tool::Tolerance(F);
3036 Standard_Real squareTolerance = aTol * aTol;
3038 // Compute parameters
3039 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
3040 aRet = new TColStd_HArray1OfReal (0, nbP * 2 - 1);
3042 Standard_Real U1,U2, V1,V2;
3043 BRepTools::UVBounds(F, U1, U2, V1, V2);
3044 Standard_Real dU = U2 - U1;
3045 Standard_Real dV = V2 - V1;
3047 int iCLower = theXYZlist->Lower();
3048 for (int iP = 0; iP < nbP; iP++) {
3049 gp_Pnt aP (theXYZlist->Value(iCLower + iP * 3),
3050 theXYZlist->Value(iCLower + iP * 3 + 1),
3051 theXYZlist->Value(iCLower + iP * 3 + 2));
3052 try { // as GEOMUtils::ProjectPointOnFace can throw exceptions
3054 gp_Pnt aPonF = GEOMUtils::ProjectPointOnFace(aP, F, U, V, aTol);
3055 if (aP.SquareDistance(aPonF) < squareTolerance) {
3057 // Normalize parameters to be in [0, 1]
3061 aRet->SetValue(iP * 2 , U);
3062 aRet->SetValue(iP * 2 + 1, V);
3065 SetErrorCode("Point too far from face");
3069 catch (Standard_Failure& aFail) {
3070 SetErrorCode(aFail.GetMessageString());
3079 //=============================================================================
3083 //=============================================================================
3084 Handle(TColStd_HArray1OfReal) GEOMImpl_IMeasureOperations::UVtoXYZ
3085 (Handle(GEOM_Object) theSurf,
3086 const Handle(TColStd_HArray1OfReal)& theUVlist,
3091 Handle(TColStd_HArray1OfReal) aRet;
3093 // Check list of parameters
3094 int nbC = theUVlist->Length();
3096 if (nbP * 2 != nbC) {
3097 SetErrorCode("Parameters list length is not divisible by 2");
3102 if (theSurf.IsNull()) {
3103 SetErrorCode("The shape is NULL");
3107 Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
3108 if (aRefShape.IsNull()) {
3109 SetErrorCode("The shape is NULL");
3113 TopoDS_Shape aShape = aRefShape->GetValue();
3114 if (aShape.IsNull()) {
3115 SetErrorCode("The shape is NULL");
3119 // The shape can be a face, a shell of one face or a compound with one face
3121 if (aShape.ShapeType() == TopAbs_FACE) {
3122 F = TopoDS::Face(aShape);
3124 else if (aShape.ShapeType() < TopAbs_FACE) {
3125 TopExp_Explorer Exp (aShape, TopAbs_FACE);
3127 F = TopoDS::Face(Exp.Current());
3130 SetErrorCode("There should be only one face");
3136 SetErrorCode("There are no faces");
3141 Standard_Real squareTolerance = BRep_Tool::Tolerance(F);
3142 squareTolerance = squareTolerance * squareTolerance;
3144 // Compute coordinates
3145 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
3146 aRet = new TColStd_HArray1OfReal (0, nbP * 3 - 1);
3148 Standard_Real U1,U2, V1,V2;
3149 BRepTools::UVBounds(F, U1, U2, V1, V2);
3150 Standard_Real dU = U2 - U1;
3151 Standard_Real dV = V2 - V1;
3153 Standard_Real tol = 1.e-4;
3154 Standard_Real pc = Precision::Confusion();
3156 int iCLower = theUVlist->Lower();
3157 for (int iP = 0; iP < nbP; iP++) {
3158 Standard_Real U = theUVlist->Value(iCLower + iP * 2);
3159 Standard_Real V = theUVlist->Value(iCLower + iP * 2 + 1);
3162 // Get real parameters from given normalized ones in [0, 1]
3163 if (!(-pc < U && U < 1 + pc) || !(-pc < V && V < 1 + pc)) {
3164 SetErrorCode("Normalized parameter is out of range [0,1]");
3171 gp_Pnt2d aP2d (U, V);
3173 BRepClass_FaceClassifier aClsf (F, aP2d, tol);
3174 if (aClsf.State() != TopAbs_IN && aClsf.State() != TopAbs_ON) {
3175 SetErrorCode("Given parameters are out of face");
3178 gp_Pnt surfPnt = aSurf->Value(U, V);
3180 aRet->SetValue(iP * 3 , surfPnt.X());
3181 aRet->SetValue(iP * 3 + 1, surfPnt.Y());
3182 aRet->SetValue(iP * 3 + 2, surfPnt.Z());
3189 //=============================================================================
3192 * Find all self-intersected 2D curves.
3193 * \param theChecks list of failed checks, contains type of check and failed shapes
3195 //=============================================================================
3196 std::list<GEOMImpl_IMeasureOperations::CoupleOfObjects>
3197 GEOMImpl_IMeasureOperations::SelfIntersected2D(const std::list<FailedChecks>& theChecks)
3200 MESSAGE("GEOMImpl_IMeasureOperations::selfIntersected2D");
3202 std::list<GEOMImpl_IMeasureOperations::CoupleOfObjects> aSelfInters2D;
3206 for (std::list<FailedChecks>::const_iterator anIter(theChecks.begin());
3207 anIter != theChecks.end(); ++anIter)
3209 if (anIter->TypeOfCheck == BOPAlgo_CheckStatus::BOPAlgo_InvalidCurveOnSurface)
3210 aSelfInters2D.push_back(anIter->FailedShapes);
3213 catch (Standard_Failure& aFail)
3215 SetErrorCode(aFail.GetMessageString());
3216 return aSelfInters2D;
3220 return aSelfInters2D;
3225 static bool checkTypes(const GEOMImpl_IMeasureOperations::CoupleOfObjects& theShapes,
3226 const int theShapeType1,
3227 const int theShapeType2)
3229 if (theShapeType1 == -1 && theShapeType2 == -1)
3232 TopAbs_ShapeEnum aShapeType1 = theShapes.first.IsNull()
3234 : theShapes.first->GetValue().ShapeType();
3235 TopAbs_ShapeEnum aShapeType2 = theShapes.second.IsNull()
3237 : theShapes.second->GetValue().ShapeType();
3239 if (theShapeType1 == -1)
3240 return aShapeType1 == theShapeType2 || aShapeType2 == theShapeType2;
3241 else if (theShapeType2 == -1)
3242 return aShapeType1 == theShapeType1 || aShapeType2 == theShapeType1;
3243 return (aShapeType1 == theShapeType1 && aShapeType2 == theShapeType2) ||
3244 (aShapeType1 == theShapeType2 && aShapeType2 == theShapeType1);
3248 //=============================================================================
3250 * InterferingSubshapes
3251 * Find pairs of interfering sub-shapes, by default all pairs of interfering shapes are returned.
3252 * \param theChecks list of failed checks, contains type of check and failed shapes
3253 * \param theShapeType1 Type of shape.
3254 * \param theShapeType2 Type of shape.
3256 //=============================================================================
3257 std::list<GEOMImpl_IMeasureOperations::CoupleOfObjects>
3258 GEOMImpl_IMeasureOperations::InterferingSubshapes
3259 (const std::list<FailedChecks>& theChecks,
3260 const int theShapeType1,
3261 const int theShapeType2)
3264 MESSAGE("GEOMImpl_IMeasureOperations::interferingSubshapes");
3266 std::list<GEOMImpl_IMeasureOperations::CoupleOfObjects> anInterfer;
3270 for (std::list<FailedChecks>::const_iterator anIter(theChecks.begin());
3271 anIter != theChecks.end(); ++anIter)
3273 if (anIter->TypeOfCheck == BOPAlgo_CheckStatus::BOPAlgo_SelfIntersect &&
3274 checkTypes(anIter->FailedShapes, theShapeType1, theShapeType2))
3275 anInterfer.push_back(anIter->FailedShapes);
3278 catch (Standard_Failure& aFail)
3280 SetErrorCode(aFail.GetMessageString());
3288 //=============================================================================
3291 * Find edges, which are fully covered by tolerances of vertices.
3292 * \param theChecks list of failed checks, contains type of check and failed shapes
3294 //=============================================================================
3295 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IMeasureOperations::SmallEdges(
3296 const std::list<FailedChecks>& theChecks)
3299 MESSAGE("GEOMImpl_IMeasureOperations::smallEdges");
3301 Handle(TColStd_HSequenceOfTransient) aSmallEdges = new TColStd_HSequenceOfTransient;
3305 for (std::list<FailedChecks>::const_iterator anIter(theChecks.begin());
3306 anIter != theChecks.end(); ++anIter)
3308 if (anIter->TypeOfCheck == BOPAlgo_CheckStatus::BOPAlgo_TooSmallEdge)
3309 aSmallEdges->Append(anIter->FailedShapes.first);
3312 catch (Standard_Failure& aFail)
3314 SetErrorCode(aFail.GetMessageString());
3322 //=============================================================================
3325 * find remote objects (sub-shape on a shape).
3326 * \param theShape Shape for check.
3327 * \param theShapeType Type of shape.
3328 * \param theSubShapeType Type of sub-shape.
3329 * \param theTolerance tolerance.
3331 //=============================================================================
3332 std::list<GEOMImpl_IMeasureOperations::CoupleOfObjects>
3333 GEOMImpl_IMeasureOperations::DistantShapes
3334 (const std::list<FailedChecks>& theChecks,
3335 const int theShapeType,
3336 const int theSubShapeType,
3337 double theTolerance)
3340 MESSAGE("GEOMImpl_IMeasureOperations::distantShapes");
3342 std::list<GEOMImpl_IMeasureOperations::CoupleOfObjects> aDistShapes;
3346 for (std::list<FailedChecks>::const_iterator anIter(theChecks.begin());
3347 anIter != theChecks.end(); ++anIter)
3349 Handle(GEOM_Object) aSubShape = anIter->FailedShapes.first;
3350 Handle(GEOM_Object) aShape = anIter->FailedShapes.second;
3351 if ((anIter->TypeOfCheck == BOPAlgo_CheckStatus::BOPAlgo_InvalidCurveOnSurface ||
3352 anIter->TypeOfCheck == BOPAlgo_CheckStatus::BOPAlgo_IncompatibilityOfVertex ||
3353 anIter->TypeOfCheck == BOPAlgo_CheckStatus::BOPAlgo_IncompatibilityOfEdge ||
3354 anIter->TypeOfCheck == BOPAlgo_CheckStatus::BOPAlgo_IncompatibilityOfFace) &&
3355 aShape && (theShapeType == -1 || aShape->GetValue().ShapeType() == theShapeType) &&
3356 aSubShape && (theSubShapeType == -1 || aSubShape->GetValue().ShapeType() == theSubShapeType))
3359 Standard_Real aDist = Precision::Infinite();
3360 if (anIter->TypeOfCheck == BOPAlgo_CheckStatus::BOPAlgo_InvalidCurveOnSurface)
3361 aDist = ComputeTolerance(aSubShape, aShape);
3362 if (aDist > theTolerance)
3363 aDistShapes.push_back(anIter->FailedShapes);
3367 catch (Standard_Failure& aFail)
3369 SetErrorCode(aFail.GetMessageString());
3377 //=============================================================================
3379 * CheckConformityShape
3380 * Perform analyse of shape and find imperfections in the shape.
3381 * \param theShape Shape for analyse.
3383 //=============================================================================
3384 void GEOMImpl_IMeasureOperations::CheckConformityShape(Handle(GEOM_Object) theShape, std::list<FailedChecks>& theChecks)
3387 MESSAGE("GEOMImpl_IMeasureOperations::checkShape");
3389 Handle(GEOM_Object) aConformity = GetEngine()->AddObject(GEOM_CHECKCONFORMITY);
3390 Handle(GEOM_Function) aFunction = aConformity->AddFunction(GEOMImpl_ConformityDriver::GetID(), CONFORMITY_CHECK_SHAPE);
3391 if (aFunction.IsNull()) return;
3393 //Check if the function is set correctly
3394 if (aFunction->GetDriverGUID() != GEOMImpl_ConformityDriver::GetID()) return;
3396 GEOMImpl_IConformity aCI(aFunction);
3398 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
3399 if (aRefShape.IsNull()) return;
3401 aCI.SetShape(aRefShape);
3406 if (!GetSolver()->ComputeFunction(aFunction))
3408 SetErrorCode("Failed: checkShape");
3411 Handle(TColStd_HArray1OfInteger) aTypesChecks = aFunction->GetIntegerArray(CHECKCONFORMITY_RET_TYPES_CHECKS);
3412 Handle(TColStd_HArray2OfInteger) aRes = aCI.GetListOfShapesIndices();
3416 for (Standard_Integer anIndex = 1; anIndex <= aRes->NbRows(); ++anIndex)
3418 std::pair<Handle(GEOM_Object), Handle(GEOM_Object)> aPair;
3419 Handle(TColStd_HArray1OfInteger) anArray;
3420 anArray = new TColStd_HArray1OfInteger(1, 1);
3421 anArray->SetValue(1, aRes->Value(anIndex, 1));
3423 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
3424 if (!anObj.IsNull())
3425 aPair.first = anObj;
3427 anArray = new TColStd_HArray1OfInteger(1, 1);
3428 anArray->SetValue(1, aRes->Value(anIndex, 2));
3430 anObj = GetEngine()->AddSubShape(theShape, anArray);
3431 if (!anObj.IsNull())
3432 aPair.second = anObj;
3433 theChecks.push_back({ aTypesChecks->Value(anIndex), aPair });
3436 catch (Standard_Failure& aFail)
3438 SetErrorCode(aFail.GetMessageString());
3446 //=============================================================================
3449 * Compute possible tolerance for the shape, minimize tolerance of shape as well
3450 * as tolerance of sub-shapes as much as possible
3451 * \param theShape Shape for compute tolerance.
3453 //=============================================================================
3454 double GEOMImpl_IMeasureOperations::UpdateTolerance(Handle(GEOM_Object) theShape)
3457 MESSAGE("GEOMImpl_IMeasureOperations::updateTolerance");
3459 double aResTol = -1;
3460 Handle(GEOM_Object) aConformity = GetEngine()->AddObject(GEOM_CHECKCONFORMITY);
3461 Handle(GEOM_Function) aFunction = aConformity->AddFunction(GEOMImpl_ConformityDriver::GetID(), CONFORMITY_UPDATE_TOL);
3462 if (aFunction.IsNull()) return aResTol;
3464 //Check if the function is set correctly
3465 if (aFunction->GetDriverGUID() != GEOMImpl_ConformityDriver::GetID()) return aResTol;
3467 GEOMImpl_IConformity aCI(aFunction);
3469 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
3470 if (aRefShape.IsNull()) return aResTol;
3472 aCI.SetShape(aRefShape);
3477 if (!GetSolver()->ComputeFunction(aFunction))
3479 SetErrorCode("Failed: updateTolerance");
3482 aResTol = aFunction->GetReal(CHECKCONFORMITY_RET_TOLERANCE);
3484 catch (Standard_Failure& aFail)
3486 SetErrorCode(aFail.GetMessageString());
3494 //=============================================================================
3497 * Compute distance from the edge to the face.
3499 //=============================================================================
3500 double GEOMImpl_IMeasureOperations::ComputeTolerance(Handle(GEOM_Object) theEdge,
3501 Handle(GEOM_Object) theFace)
3503 double aMaxDist = Precision::Infinite();
3504 if (theEdge.IsNull() || theFace.IsNull())
3507 Handle(GEOM_Function) aRefEdge = theEdge->GetLastFunction();
3508 Handle(GEOM_Function) aRefFace = theFace->GetLastFunction();
3509 if (aRefEdge.IsNull() || aRefFace.IsNull())
3512 TopoDS_Edge aEdge = TopoDS::Edge(aRefEdge->GetValue());
3513 TopoDS_Face aFace = TopoDS::Face(aRefFace->GetValue());
3514 if (aEdge.IsNull() || aFace.IsNull())
3517 double aParam = 0.0;
3518 BOPTools_AlgoTools::ComputeTolerance(aFace, aEdge, aMaxDist, aParam);
3522 //=======================================================================
3523 //function : FillErrorsSub
3524 //purpose : Fill the errors list of subshapes on shape.
3525 //=======================================================================
3526 void GEOMImpl_IMeasureOperations::FillErrorsSub
3527 (const BRepCheck_Analyzer &theAna,
3528 const TopoDS_Shape &theShape,
3529 const TopAbs_ShapeEnum theSubType,
3530 TopTools_DataMapOfIntegerListOfShape &theMapErrors) const
3532 TopExp_Explorer anExp(theShape, theSubType);
3533 TopTools_MapOfShape aMapSubShapes;
3535 for (; anExp.More(); anExp.Next()) {
3536 const TopoDS_Shape &aSubShape = anExp.Current();
3538 if (aMapSubShapes.Add(aSubShape)) {
3539 const Handle(BRepCheck_Result) &aRes = theAna.Result(aSubShape);
3541 for (aRes->InitContextIterator();
3542 aRes->MoreShapeInContext();
3543 aRes->NextShapeInContext()) {
3544 if (aRes->ContextualShape().IsSame(theShape)) {
3545 BRepCheck_ListIteratorOfListOfStatus itl(aRes->StatusOnShape());
3547 if (itl.Value() != BRepCheck_NoError) {
3548 // Add all errors for theShape and its sub-shape.
3549 for (;itl.More(); itl.Next()) {
3550 const Standard_Integer aStat = (Standard_Integer)itl.Value();
3552 if (!theMapErrors.IsBound(aStat)) {
3553 TopTools_ListOfShape anEmpty;
3555 theMapErrors.Bind(aStat, anEmpty);
3558 TopTools_ListOfShape &theShapes = theMapErrors.ChangeFind(aStat);
3560 theShapes.Append(aSubShape);
3561 theShapes.Append(theShape);
3572 //=======================================================================
3573 //function : FillErrors
3574 //purpose : Fill the errors list.
3575 //=======================================================================
3576 void GEOMImpl_IMeasureOperations::FillErrors
3577 (const BRepCheck_Analyzer &theAna,
3578 const TopoDS_Shape &theShape,
3579 TopTools_DataMapOfIntegerListOfShape &theMapErrors,
3580 TopTools_MapOfShape &theMapShapes) const
3582 if (theMapShapes.Add(theShape)) {
3583 // Fill errors of child shapes.
3584 for (TopoDS_Iterator iter(theShape); iter.More(); iter.Next()) {
3585 FillErrors(theAna, iter.Value(), theMapErrors, theMapShapes);
3588 // Fill errors of theShape.
3589 const Handle(BRepCheck_Result) &aRes = theAna.Result(theShape);
3591 if (!aRes.IsNull()) {
3592 BRepCheck_ListIteratorOfListOfStatus itl(aRes->Status());
3594 if (itl.Value() != BRepCheck_NoError) {
3595 // Add all errors for theShape.
3596 for (;itl.More(); itl.Next()) {
3597 const Standard_Integer aStat = (Standard_Integer)itl.Value();
3599 if (!theMapErrors.IsBound(aStat)) {
3600 TopTools_ListOfShape anEmpty;
3602 theMapErrors.Bind(aStat, anEmpty);
3605 theMapErrors.ChangeFind(aStat).Append(theShape);
3610 // Add errors of subshapes on theShape.
3611 const TopAbs_ShapeEnum aType = theShape.ShapeType();
3615 FillErrorsSub(theAna, theShape, TopAbs_VERTEX, theMapErrors);
3618 FillErrorsSub(theAna, theShape, TopAbs_WIRE, theMapErrors);
3619 FillErrorsSub(theAna, theShape, TopAbs_EDGE, theMapErrors);
3620 FillErrorsSub(theAna, theShape, TopAbs_VERTEX, theMapErrors);
3623 FillErrorsSub(theAna, theShape, TopAbs_SHELL, theMapErrors);
3631 //=======================================================================
3632 //function : FillErrors
3633 //purpose : Fill the errors list.
3634 //=======================================================================
3635 void GEOMImpl_IMeasureOperations::FillErrors
3636 (const BRepCheck_Analyzer &theAna,
3637 const TopoDS_Shape &theShape,
3638 std::list<ShapeError> &theErrors) const
3640 // Fill the errors map.
3641 TopTools_DataMapOfIntegerListOfShape aMapErrors;
3642 TopTools_MapOfShape aMapShapes;
3644 FillErrors(theAna, theShape, aMapErrors, aMapShapes);
3646 // Map sub-shapes and their indices
3647 TopTools_IndexedMapOfShape anIndices;
3649 TopExp::MapShapes(theShape, anIndices);
3651 TopTools_DataMapIteratorOfDataMapOfIntegerListOfShape aMapIter(aMapErrors);
3653 for (; aMapIter.More(); aMapIter.Next()) {
3656 anError.error = (BRepCheck_Status)aMapIter.Key();
3658 TopTools_ListIteratorOfListOfShape aListIter(aMapIter.Value());
3659 TopTools_MapOfShape aMapUnique;
3661 for (; aListIter.More(); aListIter.Next()) {
3662 const TopoDS_Shape &aShape = aListIter.Value();
3664 if (aMapUnique.Add(aShape)) {
3665 const Standard_Integer anIndex = anIndices.FindIndex(aShape);
3667 anError.incriminated.push_back(anIndex);
3671 if (!anError.incriminated.empty()) {
3672 theErrors.push_back(anError);
3677 //=======================================================================
3678 //function : ShapeProximityCalculator
3679 //purpose : returns an object to compute the proximity value
3680 //=======================================================================
3681 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::ShapeProximityCalculator
3682 (Handle(GEOM_Object) theShape1,
3683 Handle(GEOM_Object) theShape2)
3687 if (theShape1.IsNull() || theShape2.IsNull())
3690 Handle(GEOM_Function) aShapeFunc1 = theShape1->GetLastFunction();
3691 Handle(GEOM_Function) aShapeFunc2 = theShape2->GetLastFunction();
3692 if (aShapeFunc1.IsNull() || aShapeFunc2.IsNull())
3695 Handle(GEOM_Object) aProximityCalc = GetEngine()->AddObject(GEOM_SHAPE_PROXIMITY);
3696 if (aProximityCalc.IsNull())
3699 Handle(GEOM_Function) aProximityFuncCoarse =
3700 aProximityCalc->AddFunction(GEOMImpl_ShapeProximityDriver::GetID(), PROXIMITY_COARSE);
3701 //Check if the function is set correctly
3702 if (aProximityFuncCoarse.IsNull() ||
3703 aProximityFuncCoarse->GetDriverGUID() != GEOMImpl_ShapeProximityDriver::GetID())
3706 GEOMImpl_IProximity aProximity (aProximityFuncCoarse);
3707 aProximity.SetShapes(aShapeFunc1, aShapeFunc2);
3709 //Make a Python command
3710 GEOM::TPythonDump pd (aProximityFuncCoarse);
3711 pd << "p = geompy.ShapeProximity()\n";
3712 pd << "p.setShapes(" << theShape1 << ", " << theShape2 << ")";
3715 return aProximityCalc;
3718 //=======================================================================
3719 //function : SetShapeSampling
3720 //purpose : set number sample points to compute the coarse proximity
3721 //=======================================================================
3722 void GEOMImpl_IMeasureOperations::SetShapeSampling(Handle(GEOM_Object) theCalculator,
3723 Handle(GEOM_Object) theShape,
3724 const Standard_Integer theNbSamples)
3727 if (theShape.IsNull() ||
3728 theCalculator.IsNull() ||
3729 theCalculator->GetNbFunctions() <= 0 ||
3733 Handle(GEOM_Function) aProximityFuncCoarse = theCalculator->GetFunction(1);
3734 if (aProximityFuncCoarse.IsNull() ||
3735 aProximityFuncCoarse->GetDriverGUID() != GEOMImpl_ShapeProximityDriver::GetID())
3738 Handle(GEOM_Function) aShapeFunc = theShape->GetLastFunction();
3739 if (aShapeFunc.IsNull())
3742 GEOMImpl_IProximity aProximity(aProximityFuncCoarse);
3743 Handle(GEOM_Function) aShape1, aShape2;
3744 aProximity.GetShapes(aShape1, aShape2);
3745 if (aShape1->GetValue() == aShapeFunc->GetValue())
3746 aProximity.SetNbSamples(PROXIMITY_ARG_SAMPLES1, theNbSamples);
3747 else if (aShape2->GetValue() == aShapeFunc->GetValue())
3748 aProximity.SetNbSamples(PROXIMITY_ARG_SAMPLES2, theNbSamples);
3750 //Make a Python command
3751 GEOM::TPythonDump(aProximityFuncCoarse, /*append=*/true) <<
3752 "p.setSampling(" << theShape << ", " << theNbSamples << ")";
3757 //=======================================================================
3758 //function : GetCoarseProximity
3759 //purpose : compute coarse proximity
3760 //=======================================================================
3761 Standard_Real GEOMImpl_IMeasureOperations::GetCoarseProximity(Handle(GEOM_Object) theCalculator,
3765 if (theCalculator.IsNull())
3768 Handle(GEOM_Function) aProximityFuncCoarse = theCalculator->GetFunction(1);
3769 if (aProximityFuncCoarse.IsNull() ||
3770 aProximityFuncCoarse->GetDriverGUID() != GEOMImpl_ShapeProximityDriver::GetID() ||
3771 aProximityFuncCoarse->GetType() != PROXIMITY_COARSE)
3775 // We have to recompute the function each time,
3776 // because the number of samples can be changed
3779 if (!GetSolver()->ComputeFunction(aProximityFuncCoarse)) {
3780 SetErrorCode("shape proximity driver failed");
3784 catch (Standard_Failure& aFail) {
3785 SetErrorCode(aFail.GetMessageString());
3789 //Make a Python command
3791 GEOM::TPythonDump(aProximityFuncCoarse, /*append=*/true) << "value = p.coarseProximity()";
3794 GEOMImpl_IProximity aProximity (aProximityFuncCoarse);
3795 return aProximity.GetValue();
3798 //=======================================================================
3799 //function : GetPreciseProximity
3800 //purpose : compute precise proximity
3801 //=======================================================================
3802 Standard_Real GEOMImpl_IMeasureOperations::GetPreciseProximity(Handle(GEOM_Object) theCalculator)
3805 if (theCalculator.IsNull())
3808 Handle(GEOM_Function) aProximityFuncCoarse = theCalculator->GetFunction(1);
3809 Handle(GEOM_Function) aProximityFuncFine = theCalculator->GetFunction(2);
3810 if (aProximityFuncFine.IsNull())
3811 aProximityFuncFine = theCalculator->AddFunction
3812 (GEOMImpl_ShapeProximityDriver::GetID(), PROXIMITY_PRECISE);
3814 //Check if the functions are set correctly
3815 if (aProximityFuncCoarse.IsNull() ||
3816 aProximityFuncCoarse->GetDriverGUID() != GEOMImpl_ShapeProximityDriver::GetID() ||
3817 aProximityFuncFine.IsNull() ||
3818 aProximityFuncFine->GetDriverGUID() != GEOMImpl_ShapeProximityDriver::GetID())
3821 // perform coarse computation beforehand
3822 GetCoarseProximity(theCalculator, /*doPythonDump=*/false);
3824 // transfer parameters from the coarse to precise calculator
3825 GEOMImpl_IProximity aCoarseProximity (aProximityFuncCoarse);
3826 Handle(GEOM_Function) aShape1, aShape2;
3827 aCoarseProximity.GetShapes(aShape1, aShape2);
3828 if (aShape1.IsNull() || aShape2.IsNull())
3830 gp_Pnt aProxPnt1, aProxPnt2;
3831 Standard_Integer intStatus1, intStatus2;
3832 aCoarseProximity.GetProximityPoints(aProxPnt1, aProxPnt2);
3833 aCoarseProximity.GetStatusOfPoints(intStatus1, intStatus2);
3834 Standard_Real aResultValue = aCoarseProximity.GetValue();
3836 GEOMImpl_IProximity aFineProximity (aProximityFuncFine);
3837 aFineProximity.SetShapes(aShape1, aShape2);
3838 aFineProximity.SetProximityPoints(aProxPnt1, aProxPnt2);
3839 aFineProximity.SetStatusOfPoints(intStatus1, intStatus2);
3840 aFineProximity.SetValue(aResultValue); // in some cases this value cannot be precised
3845 if (!GetSolver()->ComputeFunction(aProximityFuncFine)) {
3846 SetErrorCode("shape proximity driver failed");
3850 catch (Standard_Failure& aFail) {
3851 SetErrorCode(aFail.GetMessageString());
3855 aResultValue = aFineProximity.GetValue();
3856 aFineProximity.GetProximityPoints(aProxPnt1, aProxPnt2);
3858 //Make a Python command
3859 GEOM::TPythonDump(aProximityFuncCoarse, /*append=*/true) << "value = p.preciseProximity()";
3862 return aResultValue;