1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include <Standard_Stream.hxx>
22 #include <GEOMImpl_IMeasureOperations.hxx>
24 #include <GEOMImpl_Types.hxx>
25 #include <GEOMImpl_MeasureDriver.hxx>
26 #include <GEOMImpl_IMeasure.hxx>
28 #include <GEOM_Function.hxx>
29 #include <GEOM_PythonDump.hxx>
31 #include "utilities.h"
33 #include <Utils_ExceptHandlers.hxx>
36 #include <TFunction_DriverTable.hxx>
37 #include <TFunction_Driver.hxx>
38 #include <TFunction_Logbook.hxx>
39 #include <TDF_Tool.hxx>
41 #include <BRep_Tool.hxx>
42 #include <BRepAdaptor_Surface.hxx>
43 #include <BRepBndLib.hxx>
44 #include <BRepCheck.hxx>
45 #include <BRepCheck_Result.hxx>
46 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
47 #include <BRepExtrema_DistShapeShape.hxx>
48 #include <BRepGProp.hxx>
49 #include <BRepTools.hxx>
51 #include <Bnd_Box.hxx>
53 #include <GProp_GProps.hxx>
54 #include <GProp_PrincipalProps.hxx>
58 #include <TopoDS_Edge.hxx>
59 #include <TopoDS_Face.hxx>
60 #include <TopoDS_Shape.hxx>
61 #include <TopoDS_Vertex.hxx>
62 #include <TopoDS_Iterator.hxx>
63 #include <TopExp_Explorer.hxx>
64 #include <TopTools_MapOfShape.hxx>
65 #include <TopTools_ListOfShape.hxx>
66 #include <TopTools_ListIteratorOfListOfShape.hxx>
68 #include <GeomAbs_SurfaceType.hxx>
69 #include <Geom_Surface.hxx>
70 #include <Geom_Plane.hxx>
71 #include <Geom_SphericalSurface.hxx>
72 #include <Geom_CylindricalSurface.hxx>
73 #include <Geom_ToroidalSurface.hxx>
74 #include <Geom_ConicalSurface.hxx>
75 #include <Geom_SurfaceOfLinearExtrusion.hxx>
76 #include <Geom_SurfaceOfRevolution.hxx>
77 #include <Geom_BezierSurface.hxx>
78 #include <Geom_BSplineSurface.hxx>
79 #include <Geom_RectangularTrimmedSurface.hxx>
80 #include <Geom_OffsetSurface.hxx>
84 #include <Standard_Failure.hxx>
85 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
87 //=============================================================================
91 //=============================================================================
92 GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations (GEOM_Engine* theEngine, int theDocID)
93 : GEOM_IOperations(theEngine, theDocID)
95 MESSAGE("GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations");
98 //=============================================================================
102 //=============================================================================
103 GEOMImpl_IMeasureOperations::~GEOMImpl_IMeasureOperations()
105 MESSAGE("GEOMImpl_IMeasureOperations::~GEOMImpl_IMeasureOperations");
108 //=============================================================================
109 /*! Get kind and parameters of the given shape.
111 //=============================================================================
112 GEOMImpl_IMeasureOperations::ShapeKind GEOMImpl_IMeasureOperations::KindOfShape
113 (Handle(GEOM_Object) theShape,
114 Handle(TColStd_HSequenceOfInteger)& theIntegers,
115 Handle(TColStd_HSequenceOfReal)& theDoubles)
118 ShapeKind aKind = SK_NO_SHAPE;
120 if (theIntegers.IsNull()) theIntegers = new TColStd_HSequenceOfInteger;
121 else theIntegers->Clear();
123 if (theDoubles.IsNull()) theDoubles = new TColStd_HSequenceOfReal;
124 else theDoubles->Clear();
126 if (theShape.IsNull())
129 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
130 if (aRefShape.IsNull()) return aKind;
132 TopoDS_Shape aShape = aRefShape->GetValue();
133 if (aShape.IsNull()) return aKind;
135 TopAbs_ShapeEnum aType = aShape.ShapeType();
138 //??? geompy.kind.compound nb_solids nb_faces nb_edges nb_vertices
139 //??? geompy.kind.compsolid nb_solids nb_faces nb_edges nb_vertices
140 //? "nb_faces" - all faces or only 'standalone' faces?
141 case TopAbs_COMPOUND:
145 case TopAbs_COMPSOLID:
146 aKind = SK_COMPSOLID;
150 //geompy.kind.shell geompy.info.closed nb_faces nb_edges nb_vertices
151 //geompy.kind.shell geompy.info.unclosed nb_faces nb_edges nb_vertices
156 //geompy.kind.wire geompy.info.closed nb_edges nb_vertices
157 //geompy.kind.wire geompy.info.unclosed nb_edges nb_vertices
162 //geompy.kind.sphere xc yc zc R
163 //geompy.kind.cylinder xb yb zb dx dy dz R H
164 //geompy.kind.box xc yc zc dx dy dz
165 //geompy.kind.rotated_box xo yo zo zx zy zz xx xy xz dx dy dz
166 //geompy.kind.torus xc yc zc dx dy dz R_1 R_2
167 //geompy.kind.cone xb yb zb dx dy dz H R_1 R_2
168 //geompy.kind.polyhedron nb_faces nb_edges nb_vertices
169 //geompy.kind.solid nb_faces nb_edges nb_vertices
172 // aKind = SK_SPHERE;
173 // aKind = SK_CYLINDER;
175 // aKind = SK_ROTATED_BOX;
178 // aKind = SK_POLYHEDRON;
182 // geompy.kind.sphere2d xc yc zc R
183 // + geompy.kind.cylinder2d xb yb zb dx dy dz R H
184 // geompy.kind.torus2d xc yc zc dx dy dz R_1 R_2
185 // geompy.kind.cone2d xc yc zc dx dy dz R_1 R_2
186 // geompy.kind.disk xc yc zc dx dy dz R
187 // geompy.kind.ellipse2d xc yc zc dx dy dz R_1 R_2
188 // geompy.kind.polygon xo yo zo dx dy dz nb_edges nb_vertices
189 // + geompy.kind.planar xo yo zo dx dy dz nb_edges nb_vertices
190 // + geompy.kind.face nb_edges nb_vertices _surface_type_id_
193 TopoDS_Face aF = TopoDS::Face(aShape);
195 int nbWires = 0, nbEdges = 0, nbVertices = 0;
197 TopTools_MapOfShape mapShape;
198 TopExp_Explorer expw (aF, TopAbs_WIRE);
199 for (; expw.More(); expw.Next()) {
200 if (mapShape.Add(expw.Current())) {
201 //listShape.Append(expw.Current());
207 TopExp_Explorer expe (aF, TopAbs_EDGE);
208 for (; expe.More(); expe.Next()) {
209 if (mapShape.Add(expe.Current())) {
210 //listShape.Append(expe.Current());
216 TopExp_Explorer expf (aF, TopAbs_VERTEX);
217 for (; expf.More(); expf.Next()) {
218 if (mapShape.Add(expf.Current())) {
219 //listShape.Append(expf.Current());
225 Handle(Geom_Surface) aGS = BRep_Tool::Surface(aF);
227 BRepAdaptor_Surface aBAS (aF);
229 if (aGS->IsKind(STANDARD_TYPE(Geom_Plane))) {
233 Handle(Geom_Plane) aGPlane = Handle(Geom_Plane)::DownCast(aGS);
234 gp_Pln aPln = aGPlane->Pln();
235 gp_Ax3 aPos = aPln.Position();
236 gp_Pnt anOri = aPos.Location();
237 gp_Dir aDirZ = aPos.Direction();
238 //gp_Dir aDirX = aPos.XDirection();
241 theDoubles->Append(anOri.X());
242 theDoubles->Append(anOri.Y());
243 theDoubles->Append(anOri.Z());
246 theDoubles->Append(aDirZ.X());
247 theDoubles->Append(aDirZ.Y());
248 theDoubles->Append(aDirZ.Z());
250 // nb_edges nb_vertices (for planar only)
251 theIntegers->Append(nbEdges);
252 theIntegers->Append(nbVertices);
256 // aKind = SK_ELLIPSE2D;
257 // aKind = SK_POLYGON;
260 else if (aGS->IsKind(STANDARD_TYPE(Geom_SphericalSurface))) {
261 //if (/*isSphere*/false) {
262 if (aBAS.IsUClosed() && aBAS.IsVClosed()) { // does not work
263 Handle(Geom_SphericalSurface) aGSph = Handle(Geom_SphericalSurface)::DownCast(aGS);
266 gp_Pnt aLoc = aGSph->Location();
267 Standard_Real rr = aGSph->Radius();
270 theDoubles->Append(aLoc.X());
271 theDoubles->Append(aLoc.Y());
272 theDoubles->Append(aLoc.Z());
275 theDoubles->Append(rr);
280 // nb_edges nb_vertices (for spherical only)
281 theIntegers->Append(nbEdges);
282 theIntegers->Append(nbVertices);
284 theIntegers->Append((Standard_Integer)GeomAbs_Sphere);
287 else if (aGS->IsKind(STANDARD_TYPE(Geom_CylindricalSurface))) {
288 // Pure cylinder or just a piece of cylindric surface
290 Handle(Geom_Surface) aGSLoc = BRep_Tool::Surface(aF, aL);
292 //aF.Orientation(TopAbs_FORWARD);
293 TopExp_Explorer ex (aF, TopAbs_EDGE);
294 Standard_Real uMin, uMax, vMin, vMax;
295 bool isCylinder = true;
296 for (; ex.More(); ex.Next()) {
297 // check all edges: pure cylinder has only one seam edge
298 // and two edges with const v parameter
299 TopoDS_Edge E = TopoDS::Edge(ex.Current());
301 if (BRep_Tool::IsClosed(E, aGSLoc, aL)) {
303 //TopoDS_Edge ERevr = E;
305 //Handle(Geom2d_Curve) pcRepl1 = BRep_Tool::CurveOnSurface(E , aF, f,l);
306 //Handle(Geom2d_Curve) pcRepl2 = BRep_Tool::CurveOnSurface(ERevr, aF, f,l);
309 BRepTools::UVBounds(aF, E, uMin, uMax, vMin, vMax);
310 if (Abs(vMin - vMax) > Precision::Confusion())
311 // neither seam, nor v-constant
317 aKind = SK_CYLINDER2D;
319 Handle(Geom_CylindricalSurface) aGCyl = Handle(Geom_CylindricalSurface)::DownCast(aGS);
322 gp_Pnt aLoc = aGCyl->Location();
323 gp_Ax1 anAx = aGCyl->Axis();
324 gp_Dir aDir = anAx.Direction();
325 Standard_Real rr = aGCyl->Radius();
328 theDoubles->Append(aLoc.X());
329 theDoubles->Append(aLoc.Y());
330 theDoubles->Append(aLoc.Z());
333 theDoubles->Append(aDir.X());
334 theDoubles->Append(aDir.Y());
335 theDoubles->Append(aDir.Z());
338 theDoubles->Append(rr);
341 Standard_Real hh = Abs(aBAS.FirstVParameter() - aBAS.LastVParameter());
342 theDoubles->Append(hh);
345 // nb_edges nb_vertices (for cylinrical only)
346 theIntegers->Append(nbEdges);
347 theIntegers->Append(nbVertices);
349 theIntegers->Append((Standard_Integer)GeomAbs_Cylinder);
352 else if (aGS->IsKind(STANDARD_TYPE(Geom_ToroidalSurface))) {
353 // aKind = SK_TORUS2D;
354 theIntegers->Append(nbEdges);
355 theIntegers->Append(nbVertices);
357 theIntegers->Append((Standard_Integer)GeomAbs_Torus);
359 else if (aGS->IsKind(STANDARD_TYPE(Geom_ConicalSurface))) {
360 // aKind = SK_CONE2D;
361 theIntegers->Append(nbEdges);
362 theIntegers->Append(nbVertices);
364 theIntegers->Append((Standard_Integer)GeomAbs_Cone);
366 else if (aGS->IsKind(STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion))) {
368 theIntegers->Append(nbEdges);
369 theIntegers->Append(nbVertices);
371 theIntegers->Append((Standard_Integer)GeomAbs_SurfaceOfExtrusion);
373 else if (aGS->IsKind(STANDARD_TYPE(Geom_SurfaceOfRevolution))) {
375 theIntegers->Append(nbEdges);
376 theIntegers->Append(nbVertices);
378 theIntegers->Append((Standard_Integer)GeomAbs_SurfaceOfRevolution);
380 else if (aGS->IsKind(STANDARD_TYPE(Geom_BezierSurface))) {
382 theIntegers->Append(nbEdges);
383 theIntegers->Append(nbVertices);
385 theIntegers->Append((Standard_Integer)GeomAbs_BezierSurface);
387 else if (aGS->IsKind(STANDARD_TYPE(Geom_BSplineSurface))) {
389 theIntegers->Append(nbEdges);
390 theIntegers->Append(nbVertices);
392 theIntegers->Append((Standard_Integer)GeomAbs_BSplineSurface);
394 else if (aGS->IsKind(STANDARD_TYPE(Geom_OffsetSurface))) {
396 theIntegers->Append(nbEdges);
397 theIntegers->Append(nbVertices);
399 theIntegers->Append((Standard_Integer)GeomAbs_OffsetSurface);
401 else if (aGS->IsKind(STANDARD_TYPE(Geom_RectangularTrimmedSurface))) {
403 theIntegers->Append(nbEdges);
404 theIntegers->Append(nbVertices);
406 theIntegers->Append((Standard_Integer)GeomAbs_OtherSurface);
410 theIntegers->Append(nbEdges);
411 theIntegers->Append(nbVertices);
413 theIntegers->Append((Standard_Integer)GeomAbs_OtherSurface);
419 //geompy.kind.circle xc yc zc dx dy dz R
420 //geompy.kind.arc xc yc zc dx dy dz R x1 y1 z1 x2 y2 z2
421 //geompy.kind.ellipse xc yc zc dx dy dz R_1 R_2
422 //geompy.kind.arcEllipse xc yc zc dx dy dz R_1 R_2 x1 y1 z1 x2 y2 z2
423 //geompy.kind.line x1 y1 z1 x2 y2 z2
424 //geompy.kind.segment x1 y1 z1 x2 y2 z2
425 //geompy.kind.edge nb_vertices _curve_type_id_
428 // aKind = SK_CIRCLE;
430 // aKind = SK_ELLIPSE;
431 // aKind = SK_ARC_ELLIPSE;
433 // aKind = SK_SEGMENT;
437 //geompy.kind.VERTEX x y z
440 TopoDS_Vertex aV = TopoDS::Vertex(aShape);
441 gp_Pnt aP = BRep_Tool::Pnt(aV);
442 theDoubles->Append(aP.X());
443 theDoubles->Append(aP.Y());
444 theDoubles->Append(aP.Z());
453 //=============================================================================
454 /*! Get LCS, corresponding to the given shape.
455 * Origin of the LCS is situated at the shape's center of mass.
456 * Axes of the LCS are obtained from shape's location or,
457 * if the shape is a planar face, from position of its plane.
459 //=============================================================================
460 gp_Ax3 GEOMImpl_IMeasureOperations::GetPosition (const TopoDS_Shape& theShape)
464 if (theShape.IsNull())
468 aResult.Transform(theShape.Location().Transformation());
469 if (theShape.ShapeType() == TopAbs_FACE) {
470 Handle(Geom_Surface) aGS = BRep_Tool::Surface(TopoDS::Face(theShape));
471 if (!aGS.IsNull() && aGS->IsKind(STANDARD_TYPE(Geom_Plane))) {
472 Handle(Geom_Plane) aGPlane = Handle(Geom_Plane)::DownCast(aGS);
473 gp_Pln aPln = aGPlane->Pln();
474 aResult = aPln.Position();
480 if (theShape.ShapeType() == TopAbs_VERTEX) {
481 aPnt = BRep_Tool::Pnt(TopoDS::Vertex(theShape));
484 GProp_GProps aSystem;
485 if (theShape.ShapeType() == TopAbs_EDGE || theShape.ShapeType() == TopAbs_WIRE)
486 BRepGProp::LinearProperties(theShape, aSystem);
487 else if (theShape.ShapeType() == TopAbs_FACE || theShape.ShapeType() == TopAbs_SHELL)
488 BRepGProp::SurfaceProperties(theShape, aSystem);
490 BRepGProp::VolumeProperties(theShape, aSystem);
492 aPnt = aSystem.CentreOfMass();
495 aResult.SetLocation(aPnt);
500 //=============================================================================
504 //=============================================================================
505 void GEOMImpl_IMeasureOperations::GetPosition
506 (Handle(GEOM_Object) theShape,
507 Standard_Real& Ox, Standard_Real& Oy, Standard_Real& Oz,
508 Standard_Real& Zx, Standard_Real& Zy, Standard_Real& Zz,
509 Standard_Real& Xx, Standard_Real& Xy, Standard_Real& Xz)
513 //Set default values: global CS
514 Ox = Oy = Oz = Zx = Zy = Xy = Xz = 0.;
517 if (theShape.IsNull()) return;
519 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
520 if (aRefShape.IsNull()) return;
522 TopoDS_Shape aShape = aRefShape->GetValue();
523 if (aShape.IsNull()) {
524 SetErrorCode("The Objects has NULL Shape");
529 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
533 gp_Ax3 anAx3 = GetPosition(aShape);
535 gp_Pnt anOri = anAx3.Location();
536 gp_Dir aDirZ = anAx3.Direction();
537 gp_Dir aDirX = anAx3.XDirection();
540 anOri.Coord(Ox, Oy, Oz);
541 aDirZ.Coord(Zx, Zy, Zz);
542 aDirX.Coord(Xx, Xy, Xz);
544 catch (Standard_Failure) {
545 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
546 SetErrorCode(aFail->GetMessageString());
553 //=============================================================================
557 //=============================================================================
558 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetCentreOfMass
559 (Handle(GEOM_Object) theShape)
563 if (theShape.IsNull()) return NULL;
565 //Add a new CentreOfMass object
566 Handle(GEOM_Object) aCDG = GetEngine()->AddObject(GetDocID(), GEOM_CDG);
568 //Add a new CentreOfMass function
569 Handle(GEOM_Function) aFunction =
570 aCDG->AddFunction(GEOMImpl_MeasureDriver::GetID(), CDG_MEASURE);
571 if (aFunction.IsNull()) return NULL;
573 //Check if the function is set correctly
574 if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
576 GEOMImpl_IMeasure aCI (aFunction);
578 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
579 if (aRefShape.IsNull()) return NULL;
581 aCI.SetBase(aRefShape);
583 //Compute the CentreOfMass value
585 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
588 if (!GetSolver()->ComputeFunction(aFunction)) {
589 SetErrorCode("Measure driver failed to compute centre of mass");
593 catch (Standard_Failure) {
594 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
595 SetErrorCode(aFail->GetMessageString());
599 //Make a Python command
600 GEOM::TPythonDump(aFunction) << aCDG << " = geompy.MakeCDG(" << theShape << ")";
606 //=============================================================================
610 //=============================================================================
611 void GEOMImpl_IMeasureOperations::GetBasicProperties (Handle(GEOM_Object) theShape,
612 Standard_Real& theLength,
613 Standard_Real& theSurfArea,
614 Standard_Real& theVolume)
618 if (theShape.IsNull()) return;
620 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
621 if (aRefShape.IsNull()) return;
623 TopoDS_Shape aShape = aRefShape->GetValue();
624 if (aShape.IsNull()) {
625 SetErrorCode("The Objects has NULL Shape");
629 //Compute the parameters
630 GProp_GProps LProps, SProps;
632 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
635 BRepGProp::LinearProperties(aShape, LProps);
636 theLength = LProps.Mass();
638 BRepGProp::SurfaceProperties(aShape, SProps);
639 theSurfArea = SProps.Mass();
642 if (aShape.ShapeType() < TopAbs_SHELL) {
643 for (TopExp_Explorer Exp (aShape, TopAbs_SOLID); Exp.More(); Exp.Next()) {
645 BRepGProp::VolumeProperties(Exp.Current(), VProps);
646 theVolume += VProps.Mass();
650 catch (Standard_Failure) {
651 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
652 SetErrorCode(aFail->GetMessageString());
659 //=============================================================================
663 //=============================================================================
664 void GEOMImpl_IMeasureOperations::GetInertia
665 (Handle(GEOM_Object) theShape,
666 Standard_Real& I11, Standard_Real& I12, Standard_Real& I13,
667 Standard_Real& I21, Standard_Real& I22, Standard_Real& I23,
668 Standard_Real& I31, Standard_Real& I32, Standard_Real& I33,
669 Standard_Real& Ix , Standard_Real& Iy , Standard_Real& Iz)
673 if (theShape.IsNull()) return;
675 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
676 if (aRefShape.IsNull()) return;
678 TopoDS_Shape aShape = aRefShape->GetValue();
679 if (aShape.IsNull()) {
680 SetErrorCode("The Objects has NULL Shape");
684 //Compute the parameters
688 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
691 if (aShape.ShapeType() == TopAbs_VERTEX ||
692 aShape.ShapeType() == TopAbs_EDGE ||
693 aShape.ShapeType() == TopAbs_WIRE) {
694 BRepGProp::LinearProperties(aShape, System);
695 } else if (aShape.ShapeType() == TopAbs_FACE ||
696 aShape.ShapeType() == TopAbs_SHELL) {
697 BRepGProp::SurfaceProperties(aShape, System);
699 BRepGProp::VolumeProperties(aShape, System);
701 gp_Mat I = System.MatrixOfInertia();
715 GProp_PrincipalProps Pr = System.PrincipalProperties();
716 Pr.Moments(Ix,Iy,Iz);
718 catch (Standard_Failure) {
719 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
720 SetErrorCode(aFail->GetMessageString());
727 //=============================================================================
731 //=============================================================================
732 void GEOMImpl_IMeasureOperations::GetBoundingBox
733 (Handle(GEOM_Object) theShape,
734 Standard_Real& Xmin, Standard_Real& Xmax,
735 Standard_Real& Ymin, Standard_Real& Ymax,
736 Standard_Real& Zmin, Standard_Real& Zmax)
740 if (theShape.IsNull()) return;
742 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
743 if (aRefShape.IsNull()) return;
745 TopoDS_Shape aShape = aRefShape->GetValue();
746 if (aShape.IsNull()) {
747 SetErrorCode("The Objects has NULL Shape");
751 //Compute the parameters
755 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
758 BRepBndLib::Add(aShape, B);
759 B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
761 catch (Standard_Failure) {
762 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
763 SetErrorCode(aFail->GetMessageString());
770 //=============================================================================
774 //=============================================================================
775 void GEOMImpl_IMeasureOperations::GetTolerance
776 (Handle(GEOM_Object) theShape,
777 Standard_Real& FaceMin, Standard_Real& FaceMax,
778 Standard_Real& EdgeMin, Standard_Real& EdgeMax,
779 Standard_Real& VertMin, Standard_Real& VertMax)
783 if (theShape.IsNull()) return;
785 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
786 if (aRefShape.IsNull()) return;
788 TopoDS_Shape aShape = aRefShape->GetValue();
789 if (aShape.IsNull()) {
790 SetErrorCode("The Objects has NULL Shape");
794 //Compute the parameters
796 FaceMin = EdgeMin = VertMin = RealLast();
797 FaceMax = EdgeMax = VertMax = -RealLast();
800 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
803 for (TopExp_Explorer ExF (aShape, TopAbs_FACE); ExF.More(); ExF.Next()) {
804 TopoDS_Face Face = TopoDS::Face(ExF.Current());
805 T = BRep_Tool::Tolerance(Face);
811 for (TopExp_Explorer ExE (aShape, TopAbs_EDGE); ExE.More(); ExE.Next()) {
812 TopoDS_Edge Edge = TopoDS::Edge(ExE.Current());
813 T = BRep_Tool::Tolerance(Edge);
819 for (TopExp_Explorer ExV (aShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
820 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
821 T = BRep_Tool::Tolerance(Vertex);
828 catch (Standard_Failure) {
829 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
830 SetErrorCode(aFail->GetMessageString());
837 //=============================================================================
841 //=============================================================================
842 bool GEOMImpl_IMeasureOperations::CheckShape (Handle(GEOM_Object) theShape,
843 const Standard_Boolean theIsCheckGeom,
844 TCollection_AsciiString& theDump)
848 if (theShape.IsNull()) return false;
850 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
851 if (aRefShape.IsNull()) return false;
853 TopoDS_Shape aShape = aRefShape->GetValue();
854 if (aShape.IsNull()) {
855 SetErrorCode("The Objects has NULL Shape");
859 //Compute the parameters
860 bool isValid = false;
862 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
865 BRepCheck_Analyzer ana (aShape, theIsCheckGeom);
870 StructuralDump(ana, aShape, theDump);
873 catch (Standard_Failure) {
874 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
875 SetErrorCode(aFail->GetMessageString());
883 //=============================================================================
887 //=============================================================================
888 TCollection_AsciiString GEOMImpl_IMeasureOperations::WhatIs (Handle(GEOM_Object) theShape)
892 TCollection_AsciiString Astr;
894 if (theShape.IsNull()) return Astr;
896 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
897 if (aRefShape.IsNull()) return Astr;
899 TopoDS_Shape aShape = aRefShape->GetValue();
900 if (aShape.IsNull()) {
901 SetErrorCode("The Objects has NULL Shape");
905 //Compute the parameters
906 if (aShape.ShapeType() == TopAbs_EDGE) {
907 if (BRep_Tool::Degenerated(TopoDS::Edge(aShape))) {
908 Astr = Astr + " It is a degenerated edge \n";
912 Astr = Astr + " Number of sub-shapes : \n";
915 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
918 int iType, nbTypes [TopAbs_SHAPE];
919 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
921 nbTypes[aShape.ShapeType()]++;
923 TopTools_MapOfShape aMapOfShape;
924 aMapOfShape.Add(aShape);
925 TopTools_ListOfShape aListOfShape;
926 aListOfShape.Append(aShape);
928 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
929 for (; itL.More(); itL.Next()) {
930 TopoDS_Iterator it (itL.Value());
931 for (; it.More(); it.Next()) {
932 TopoDS_Shape s = it.Value();
933 if (aMapOfShape.Add(s)) {
934 aListOfShape.Append(s);
935 nbTypes[s.ShapeType()]++;
940 Astr = Astr + " VERTEX : " + TCollection_AsciiString(nbTypes[TopAbs_VERTEX]) + "\n";
941 Astr = Astr + " EDGE : " + TCollection_AsciiString(nbTypes[TopAbs_EDGE]) + "\n";
942 Astr = Astr + " WIRE : " + TCollection_AsciiString(nbTypes[TopAbs_WIRE]) + "\n";
943 Astr = Astr + " FACE : " + TCollection_AsciiString(nbTypes[TopAbs_FACE]) + "\n";
944 Astr = Astr + " SHELL : " + TCollection_AsciiString(nbTypes[TopAbs_SHELL]) + "\n";
945 Astr = Astr + " SOLID : " + TCollection_AsciiString(nbTypes[TopAbs_SOLID]) + "\n";
946 Astr = Astr + " COMPSOLID : " + TCollection_AsciiString(nbTypes[TopAbs_COMPSOLID]) + "\n";
947 Astr = Astr + " COMPOUND : " + TCollection_AsciiString(nbTypes[TopAbs_COMPOUND]) + "\n";
948 Astr = Astr + " SHAPE : " + TCollection_AsciiString(aMapOfShape.Extent());
950 catch (Standard_Failure) {
951 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
952 SetErrorCode(aFail->GetMessageString());
960 //=============================================================================
964 //=============================================================================
965 Standard_Real GEOMImpl_IMeasureOperations::GetMinDistance
966 (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2,
967 Standard_Real& X1, Standard_Real& Y1, Standard_Real& Z1,
968 Standard_Real& X2, Standard_Real& Y2, Standard_Real& Z2)
971 Standard_Real MinDist = 1.e9;
973 if (theShape1.IsNull() || theShape2.IsNull()) return MinDist;
975 Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction();
976 Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction();
977 if (aRefShape1.IsNull() || aRefShape2.IsNull()) return MinDist;
979 TopoDS_Shape aShape1 = aRefShape1->GetValue();
980 TopoDS_Shape aShape2 = aRefShape2->GetValue();
981 if (aShape1.IsNull() || aShape2.IsNull()) {
982 SetErrorCode("One of Objects has NULL Shape");
986 //Compute the parameters
988 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
991 BRepExtrema_DistShapeShape dst (aShape1, aShape2);
993 gp_Pnt PMin1, PMin2, P1, P2;
995 for (int i = 1; i <= dst.NbSolution(); i++) {
996 P1 = dst.PointOnShape1(i);
997 P2 = dst.PointOnShape2(i);
999 Standard_Real Dist = P1.Distance(P2);
1000 if (MinDist > Dist) {
1007 PMin1.Coord(X1, Y1, Z1);
1008 PMin2.Coord(X2, Y2, Z2);
1011 catch (Standard_Failure) {
1012 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1013 SetErrorCode(aFail->GetMessageString());
1021 //=======================================================================
1022 //function : PointCoordinates
1023 //purpose : Get coordinates of point
1024 //=======================================================================
1025 void GEOMImpl_IMeasureOperations::PointCoordinates( Handle(GEOM_Object) theShape,
1026 Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ )
1030 if ( theShape.IsNull() )
1033 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1034 if ( aRefShape.IsNull() )
1037 TopoDS_Shape aShape = aRefShape->GetValue();
1038 if ( aShape.IsNull() || aShape.ShapeType() != TopAbs_VERTEX )
1040 SetErrorCode( "Shape must be a vertex" );
1045 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1048 gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
1054 catch ( Standard_Failure )
1056 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1057 SetErrorCode( aFail->GetMessageString() );
1061 //=======================================================================
1062 //function : StructuralDump
1063 //purpose : Structural (data exchange) style of output.
1064 //=======================================================================
1065 void GEOMImpl_IMeasureOperations::StructuralDump (const BRepCheck_Analyzer& theAna,
1066 const TopoDS_Shape& theShape,
1067 TCollection_AsciiString& theDump)
1071 theDump += " -- The Shape has problems :\n";
1072 theDump += " Check Count\n";
1073 theDump += " ------------------------------------------------\n";
1075 Standard_Integer last_stat = (Standard_Integer)BRepCheck_CheckFail;
1076 Handle(TColStd_HArray1OfInteger) NbProblems =
1077 new TColStd_HArray1OfInteger(1, last_stat);
1078 for (i = 1; i <= last_stat; i++)
1079 NbProblems->SetValue(i,0);
1081 Handle(TopTools_HSequenceOfShape) sl;
1082 sl = new TopTools_HSequenceOfShape();
1083 TopTools_DataMapOfShapeListOfShape theMap;
1085 GetProblemShapes(theAna, theShape, sl, NbProblems, theMap);
1088 Standard_Integer count = 0;
1089 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnCurve);
1091 theDump += " Invalid Point on Curve ................... ";
1092 theDump += TCollection_AsciiString(count) + "\n";
1094 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnCurveOnSurface);
1096 theDump += " Invalid Point on CurveOnSurface .......... ";
1097 theDump += TCollection_AsciiString(count) + "\n";
1099 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnSurface);
1101 theDump += " Invalid Point on Surface ................. ";
1102 theDump += TCollection_AsciiString(count) + "\n";
1104 count = NbProblems->Value((Standard_Integer)BRepCheck_No3DCurve);
1106 theDump += " No 3D Curve .............................. ";
1107 theDump += TCollection_AsciiString(count) + "\n";
1109 count = NbProblems->Value((Standard_Integer)BRepCheck_Multiple3DCurve);
1111 theDump += " Multiple 3D Curve ........................ ";
1112 theDump += TCollection_AsciiString(count) + "\n";
1114 count = NbProblems->Value((Standard_Integer)BRepCheck_Invalid3DCurve);
1116 theDump += " Invalid 3D Curve ......................... ";
1117 theDump += TCollection_AsciiString(count) + "\n";
1119 count = NbProblems->Value((Standard_Integer)BRepCheck_NoCurveOnSurface);
1121 theDump += " No Curve on Surface ...................... ";
1122 theDump += TCollection_AsciiString(count) + "\n";
1124 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidCurveOnSurface);
1126 theDump += " Invalid Curve on Surface ................. ";
1127 theDump += TCollection_AsciiString(count) + "\n";
1129 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidCurveOnClosedSurface);
1131 theDump += " Invalid Curve on closed Surface .......... ";
1132 theDump += TCollection_AsciiString(count) + "\n";
1134 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidSameRangeFlag);
1136 theDump += " Invalid SameRange Flag ................... ";
1137 theDump += TCollection_AsciiString(count) + "\n";
1139 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidSameParameterFlag);
1141 theDump += " Invalid SameParameter Flag ............... ";
1142 theDump += TCollection_AsciiString(count) + "\n";
1144 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidDegeneratedFlag);
1146 theDump += " Invalid Degenerated Flag ................. ";
1147 theDump += TCollection_AsciiString(count) + "\n";
1149 count = NbProblems->Value((Standard_Integer)BRepCheck_FreeEdge);
1151 theDump += " Free Edge ................................ ";
1152 theDump += TCollection_AsciiString(count) + "\n";
1154 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidMultiConnexity);
1156 theDump += " Invalid MultiConnexity ................... ";
1157 theDump += TCollection_AsciiString(count) + "\n";
1159 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidRange);
1161 theDump += " Invalid Range ............................ ";
1162 theDump += TCollection_AsciiString(count) + "\n";
1164 count = NbProblems->Value((Standard_Integer)BRepCheck_EmptyWire);
1166 theDump += " Empty Wire ............................... ";
1167 theDump += TCollection_AsciiString(count) + "\n";
1169 count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantEdge);
1171 theDump += " Redundant Edge ........................... ";
1172 theDump += TCollection_AsciiString(count) + "\n";
1174 count = NbProblems->Value((Standard_Integer)BRepCheck_SelfIntersectingWire);
1176 theDump += " Self Intersecting Wire ................... ";
1177 theDump += TCollection_AsciiString(count) + "\n";
1179 count = NbProblems->Value((Standard_Integer)BRepCheck_NoSurface);
1181 theDump += " No Surface ............................... ";
1182 theDump += TCollection_AsciiString(count) + "\n";
1184 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidWire);
1186 theDump += " Invalid Wire ............................. ";
1187 theDump += TCollection_AsciiString(count) + "\n";
1189 count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantWire);
1191 theDump += " Redundant Wire ........................... ";
1192 theDump += TCollection_AsciiString(count) + "\n";
1194 count = NbProblems->Value((Standard_Integer)BRepCheck_IntersectingWires);
1196 theDump += " Intersecting Wires ....................... ";
1197 theDump += TCollection_AsciiString(count) + "\n";
1199 count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidImbricationOfWires);
1201 theDump += " Invalid Imbrication of Wires ............. ";
1202 theDump += TCollection_AsciiString(count) + "\n";
1204 count = NbProblems->Value((Standard_Integer)BRepCheck_EmptyShell);
1206 theDump += " Empty Shell .............................. ";
1207 theDump += TCollection_AsciiString(count) + "\n";
1209 count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantFace);
1211 theDump += " Redundant Face ........................... ";
1212 theDump += TCollection_AsciiString(count) + "\n";
1214 count = NbProblems->Value((Standard_Integer)BRepCheck_UnorientableShape);
1216 theDump += " Unorientable Shape ....................... ";
1217 theDump += TCollection_AsciiString(count) + "\n";
1219 count = NbProblems->Value((Standard_Integer)BRepCheck_NotClosed);
1221 theDump += " Not Closed ............................... ";
1222 theDump += TCollection_AsciiString(count) + "\n";
1224 count = NbProblems->Value((Standard_Integer)BRepCheck_NotConnected);
1226 theDump += " Not Connected ............................ ";
1227 theDump += TCollection_AsciiString(count) + "\n";
1229 count = NbProblems->Value((Standard_Integer)BRepCheck_SubshapeNotInShape);
1231 theDump += " Subshape not in Shape .................... ";
1232 theDump += TCollection_AsciiString(count) + "\n";
1234 count = NbProblems->Value((Standard_Integer)BRepCheck_BadOrientation);
1236 theDump += " Bad Orientation .......................... ";
1237 theDump += TCollection_AsciiString(count) + "\n";
1239 count = NbProblems->Value((Standard_Integer)BRepCheck_BadOrientationOfSubshape);
1241 theDump += " Bad Orientation of Subshape .............. ";
1242 theDump += TCollection_AsciiString(count) + "\n";
1244 count = NbProblems->Value((Standard_Integer)BRepCheck_CheckFail);
1246 theDump += " checkshape failure ....................... ";
1247 theDump += TCollection_AsciiString(count) + "\n";
1250 theDump += " ------------------------------------------------\n";
1251 theDump += "*** Shapes with problems : ";
1252 theDump += TCollection_AsciiString(sl->Length()) + "\n";
1254 Standard_Integer nbv, nbe, nbw, nbf, nbs, nbo;
1255 nbv = nbe = nbw = nbf = nbs = nbo = 0;
1257 for (i = 1; i <= sl->Length(); i++) {
1258 TopoDS_Shape shi = sl->Value(i);
1259 TopAbs_ShapeEnum sti = shi.ShapeType();
1261 case TopAbs_VERTEX : nbv++; break;
1262 case TopAbs_EDGE : nbe++; break;
1263 case TopAbs_WIRE : nbw++; break;
1264 case TopAbs_FACE : nbf++; break;
1265 case TopAbs_SHELL : nbs++; break;
1266 case TopAbs_SOLID : nbo++; break;
1272 theDump += "VERTEX : ";
1273 if (nbv < 10) theDump += " ";
1274 theDump += TCollection_AsciiString(nbv) + "\n";
1277 theDump += "EDGE : ";
1278 if (nbe < 10) theDump += " ";
1279 theDump += TCollection_AsciiString(nbe) + "\n";
1282 theDump += "WIRE : ";
1283 if (nbw < 10) theDump += " ";
1284 theDump += TCollection_AsciiString(nbw) + "\n";
1287 theDump += "FACE : ";
1288 if (nbf < 10) theDump += " ";
1289 theDump += TCollection_AsciiString(nbf) + "\n";
1292 theDump += "SHELL : ";
1293 if (nbs < 10) theDump += " ";
1294 theDump += TCollection_AsciiString(nbs) + "\n";
1297 theDump += "SOLID : ";
1298 if (nbo < 10) theDump += " ";
1299 theDump += TCollection_AsciiString(nbo) + "\n";
1303 //=======================================================================
1304 //function : GetProblemShapes
1305 // purpose : for StructuralDump
1306 //=======================================================================
1307 void GEOMImpl_IMeasureOperations::GetProblemShapes (const BRepCheck_Analyzer& theAna,
1308 const TopoDS_Shape& theShape,
1309 Handle(TopTools_HSequenceOfShape)& sl,
1310 Handle(TColStd_HArray1OfInteger)& NbProblems,
1311 TopTools_DataMapOfShapeListOfShape& theMap)
1313 for (TopoDS_Iterator iter(theShape); iter.More(); iter.Next()) {
1314 GetProblemShapes(theAna, iter.Value(), sl, NbProblems, theMap);
1316 TopAbs_ShapeEnum styp = theShape.ShapeType();
1317 BRepCheck_ListIteratorOfListOfStatus itl;
1318 TopTools_ListOfShape empty;
1319 if (!theMap.IsBound(theShape)) {
1320 theMap.Bind(theShape,empty);
1322 if (!theAna.Result(theShape).IsNull()) {
1323 itl.Initialize(theAna.Result(theShape)->Status());
1324 // !!! May be, we have to print all the problems, not only the first one ?
1325 if (itl.Value() != BRepCheck_NoError) {
1326 sl->Append(theShape);
1327 BRepCheck_Status stat = itl.Value();
1328 NbProblems->SetValue((Standard_Integer)stat,
1329 NbProblems->Value((Standard_Integer)stat) + 1);
1336 GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_VERTEX, theMap);
1339 GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_WIRE, theMap);
1340 GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_EDGE, theMap);
1341 GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_VERTEX, theMap);
1346 GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_SHELL, theMap);
1353 //=======================================================================
1354 //function : Contains
1355 //=======================================================================
1356 static Standard_Boolean Contains (const TopTools_ListOfShape& L,
1357 const TopoDS_Shape& S)
1359 TopTools_ListIteratorOfListOfShape it;
1360 for (it.Initialize(L); it.More(); it.Next()) {
1361 if (it.Value().IsSame(S)) {
1362 return Standard_True;
1365 return Standard_False;
1368 //=======================================================================
1369 //function : GetProblemSub
1370 // purpose : for StructuralDump
1371 //=======================================================================
1372 void GEOMImpl_IMeasureOperations::GetProblemSub (const BRepCheck_Analyzer& theAna,
1373 const TopoDS_Shape& theShape,
1374 Handle(TopTools_HSequenceOfShape)& sl,
1375 Handle(TColStd_HArray1OfInteger)& NbProblems,
1376 const TopAbs_ShapeEnum Subtype,
1377 TopTools_DataMapOfShapeListOfShape& theMap)
1379 BRepCheck_ListIteratorOfListOfStatus itl;
1380 TopExp_Explorer exp;
1381 for (exp.Init(theShape, Subtype); exp.More(); exp.Next()) {
1382 const TopoDS_Shape& sub = exp.Current();
1384 const Handle(BRepCheck_Result)& res = theAna.Result(sub);
1385 for (res->InitContextIterator();
1386 res->MoreShapeInContext();
1387 res->NextShapeInContext()) {
1388 if (res->ContextualShape().IsSame(theShape) && !Contains(theMap(sub), theShape)) {
1389 theMap(sub).Append(theShape);
1390 itl.Initialize(res->StatusOnShape());
1392 if (itl.Value() != BRepCheck_NoError) {
1393 Standard_Integer ii = 0;
1395 for (ii = 1; ii <= sl->Length(); ii++)
1396 if (sl->Value(ii).IsSame(sub)) break;
1398 if (ii > sl->Length()) {
1400 BRepCheck_Status stat = itl.Value();
1401 NbProblems->SetValue((Standard_Integer)stat,
1402 NbProblems->Value((Standard_Integer)stat) + 1);
1404 for (ii = 1; ii <= sl->Length(); ii++)
1405 if (sl->Value(ii).IsSame(theShape)) break;
1406 if (ii > sl->Length()) {
1407 sl->Append(theShape);
1408 BRepCheck_Status stat = itl.Value();
1409 NbProblems->SetValue((Standard_Integer)stat,
1410 NbProblems->Value((Standard_Integer)stat) + 1);