+ //Compute the parameters
+ GProp_GProps System;
+
+ try {
+#if OCC_VERSION_LARGE > 0x06010000
+ OCC_CATCH_SIGNALS;
+#endif
+ if (aShape.ShapeType() == TopAbs_VERTEX ||
+ aShape.ShapeType() == TopAbs_EDGE ||
+ aShape.ShapeType() == TopAbs_WIRE) {
+ BRepGProp::LinearProperties(aShape, System);
+ } else if (aShape.ShapeType() == TopAbs_FACE ||
+ aShape.ShapeType() == TopAbs_SHELL) {
+ BRepGProp::SurfaceProperties(aShape, System);
+ } else {
+ BRepGProp::VolumeProperties(aShape, System);
+ }
+ gp_Mat I = System.MatrixOfInertia();
+
+ I11 = I(1,1);
+ I12 = I(1,2);
+ I13 = I(1,3);
+
+ I21 = I(2,1);
+ I22 = I(2,2);
+ I23 = I(2,3);
+
+ I31 = I(3,1);
+ I32 = I(3,2);
+ I33 = I(3,3);
+
+ GProp_PrincipalProps Pr = System.PrincipalProperties();
+ Pr.Moments(Ix,Iy,Iz);
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return;
+ }
+
+ SetErrorCode(OK);
+}
+
+//=============================================================================
+/*!
+ * GetBoundingBox
+ */
+//=============================================================================
+void GEOMImpl_IMeasureOperations::GetBoundingBox
+ (Handle(GEOM_Object) theShape,
+ Standard_Real& Xmin, Standard_Real& Xmax,
+ Standard_Real& Ymin, Standard_Real& Ymax,
+ Standard_Real& Zmin, Standard_Real& Zmax)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull()) return;
+
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (aRefShape.IsNull()) return;
+
+ TopoDS_Shape aShape = aRefShape->GetValue();
+ if (aShape.IsNull()) {
+ SetErrorCode("The Objects has NULL Shape");
+ return;
+ }
+
+ //Compute the parameters
+ Bnd_Box B;
+
+ try {
+#if OCC_VERSION_LARGE > 0x06010000
+ OCC_CATCH_SIGNALS;
+#endif
+ BRepBndLib::Add(aShape, B);
+ B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return;
+ }
+
+ SetErrorCode(OK);
+}
+
+//=============================================================================
+/*!
+ * GetTolerance
+ */
+//=============================================================================
+void GEOMImpl_IMeasureOperations::GetTolerance
+ (Handle(GEOM_Object) theShape,
+ Standard_Real& FaceMin, Standard_Real& FaceMax,
+ Standard_Real& EdgeMin, Standard_Real& EdgeMax,
+ Standard_Real& VertMin, Standard_Real& VertMax)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull()) return;
+
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (aRefShape.IsNull()) return;
+
+ TopoDS_Shape aShape = aRefShape->GetValue();
+ if (aShape.IsNull()) {
+ SetErrorCode("The Objects has NULL Shape");
+ return;
+ }
+
+ //Compute the parameters
+ Standard_Real T;
+ FaceMin = EdgeMin = VertMin = RealLast();
+ FaceMax = EdgeMax = VertMax = -RealLast();
+
+ try {
+#if OCC_VERSION_LARGE > 0x06010000
+ OCC_CATCH_SIGNALS;
+#endif
+ for (TopExp_Explorer ExF (aShape, TopAbs_FACE); ExF.More(); ExF.Next()) {
+ TopoDS_Face Face = TopoDS::Face(ExF.Current());
+ T = BRep_Tool::Tolerance(Face);
+ if (T > FaceMax)
+ FaceMax = T;
+ if (T < FaceMin)
+ FaceMin = T;
+ }
+ for (TopExp_Explorer ExE (aShape, TopAbs_EDGE); ExE.More(); ExE.Next()) {
+ TopoDS_Edge Edge = TopoDS::Edge(ExE.Current());
+ T = BRep_Tool::Tolerance(Edge);
+ if (T > EdgeMax)
+ EdgeMax = T;
+ if (T < EdgeMin)
+ EdgeMin = T;
+ }
+ for (TopExp_Explorer ExV (aShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
+ TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
+ T = BRep_Tool::Tolerance(Vertex);
+ if (T > VertMax)
+ VertMax = T;
+ if (T < VertMin)
+ VertMin = T;
+ }
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return;
+ }
+
+ SetErrorCode(OK);
+}
+
+//=============================================================================
+/*!
+ * CheckShape
+ */
+//=============================================================================
+bool GEOMImpl_IMeasureOperations::CheckShape (Handle(GEOM_Object) theShape,
+ const Standard_Boolean theIsCheckGeom,
+ TCollection_AsciiString& theDump)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull()) return false;
+
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (aRefShape.IsNull()) return false;
+
+ TopoDS_Shape aShape = aRefShape->GetValue();
+ if (aShape.IsNull()) {
+ SetErrorCode("The Objects has NULL Shape");
+ return false;
+ }
+
+ //Compute the parameters
+ bool isValid = false;
+ try {
+#if OCC_VERSION_LARGE > 0x06010000
+ OCC_CATCH_SIGNALS;
+#endif
+ BRepCheck_Analyzer ana (aShape, theIsCheckGeom);
+ if (ana.IsValid()) {
+ theDump.Clear();
+ isValid = true;
+ } else {
+ StructuralDump(ana, aShape, theDump);
+ }
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return false;
+ }
+
+ SetErrorCode(OK);
+ return isValid;
+}
+
+//=============================================================================
+/*!
+ * CheckSelfIntersections
+ */
+//=============================================================================
+bool GEOMImpl_IMeasureOperations::CheckSelfIntersections
+ (Handle(GEOM_Object) theShape,
+ Handle(TColStd_HSequenceOfInteger)& theIntersections)
+{
+ SetErrorCode(KO);
+ bool isGood = false;
+
+ if (theIntersections.IsNull())
+ theIntersections = new TColStd_HSequenceOfInteger;
+ else
+ theIntersections->Clear();
+
+ if (theShape.IsNull())
+ return isGood;
+
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (aRefShape.IsNull()) return isGood;
+
+ TopoDS_Shape aShape = aRefShape->GetValue();
+ if (aShape.IsNull()) return isGood;
+
+ // 0. Prepare data
+ BRep_Builder aBB;
+ TopoDS_Compound aCS;
+ TopoDS_Shape aScopy;
+ NMTDS_Tools::CopyShape(aShape, aScopy);
+
+ // Map sub-shapes and their indices
+ TopTools_IndexedMapOfShape anIndices;
+ TopExp::MapShapes(aScopy, anIndices);
+
+ aBB.MakeCompound(aCS);
+ aBB.Add(aCS, aScopy);
+
+ NMTTools_CheckerSI aCSI; // checker of self-interferences
+ aCSI.SetCompositeShape(aCS);
+
+ // 1. Launch the checker
+ aCSI.Perform();
+ Standard_Integer iErr = aCSI.StopStatus();
+ if (iErr) {
+ return false; // Error
+ }
+
+ isGood = true;
+
+ // 2. Take the shapes from DS
+ const NMTDS_ShapesDataStructure& aDS = *(aCSI.DS());
+ Standard_Integer aNbS = aDS.NumberOfShapesOfTheObject();
+
+ // 3. Get the pairs of interfered shapes
+ NMTDS_PInterfPool pIP = aCSI.IP();
+ //const NMTDS_ListOfPassKeyBoolean& aLPKB = pIP->Get();
+ const NMTDS_ListOfPairBoolean& aLPKB = pIP->Get();
+
+ Standard_Integer n1, n2;
+ //NMTDS_ListIteratorOfListOfPassKeyBoolean aIt;
+ NMTDS_ListIteratorOfListOfPairBoolean aIt;
+
+ aIt.Initialize(aLPKB);
+ for (; aIt.More(); aIt.Next()) {
+ //const NMTDS_PassKeyBoolean& aPKB = aIt.Value();
+ const NMTDS_PairBoolean& aPKB = aIt.Value();
+ aPKB.Ids(n1, n2);
+
+ if (n1 > aNbS || n2 > aNbS)
+ return false; // Error
+
+ const TopoDS_Shape& aS1 = aDS.Shape(n1);
+ const TopoDS_Shape& aS2 = aDS.Shape(n2);
+
+ theIntersections->Append(anIndices.FindIndex(aS1));
+ theIntersections->Append(anIndices.FindIndex(aS2));
+ isGood = false;
+ }
+
+ SetErrorCode(OK);
+ return isGood;
+}
+
+//=============================================================================
+/*!
+ * IsGoodForSolid
+ */
+//=============================================================================
+TCollection_AsciiString GEOMImpl_IMeasureOperations::IsGoodForSolid (Handle(GEOM_Object) theShape)
+{
+ SetErrorCode(KO);
+
+ TCollection_AsciiString aRes = "";
+
+ if (theShape.IsNull()) {
+ aRes = "WRN_NULL_OBJECT_OR_SHAPE";
+ }
+ else {
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (aRefShape.IsNull()) {
+ aRes = "WRN_NULL_OBJECT_OR_SHAPE";
+ }
+ else {
+ TopoDS_Shape aShape = aRefShape->GetValue();
+ if (aShape.IsNull()) {
+ aRes = "WRN_NULL_OBJECT_OR_SHAPE";
+ }
+ else {
+ if (aShape.ShapeType() == TopAbs_COMPOUND) {
+ TopoDS_Iterator It (aShape, Standard_True, Standard_True);
+ if (It.More()) aShape = It.Value();
+ }
+ if (aShape.ShapeType() == TopAbs_SHELL) {
+ BRepCheck_Shell chkShell (TopoDS::Shell(aShape));
+ if (chkShell.Closed() == BRepCheck_NotClosed) {
+ aRes = "WRN_SHAPE_UNCLOSED";
+ }
+ }
+ else {
+ aRes = "WRN_SHAPE_NOT_SHELL";
+ }
+ }
+ }
+ }
+
+ if (aRes.IsEmpty())
+ SetErrorCode(OK);
+
+ return aRes;
+}
+
+//=============================================================================
+/*!
+ * WhatIs
+ */
+//=============================================================================
+TCollection_AsciiString GEOMImpl_IMeasureOperations::WhatIs (Handle(GEOM_Object) theShape)
+{
+ SetErrorCode(KO);
+
+ TCollection_AsciiString Astr;
+
+ if (theShape.IsNull()) return Astr;
+
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (aRefShape.IsNull()) return Astr;
+
+ TopoDS_Shape aShape = aRefShape->GetValue();
+ if (aShape.IsNull()) {
+ SetErrorCode("The Objects has NULL Shape");
+ return Astr;
+ }
+
+ //Compute the parameters
+ if (aShape.ShapeType() == TopAbs_EDGE) {
+ if (BRep_Tool::Degenerated(TopoDS::Edge(aShape))) {
+ Astr = Astr + " It is a degenerated edge \n";
+ }
+ }
+
+ Astr = Astr + " Number of sub-shapes : \n";
+
+ try {
+#if OCC_VERSION_LARGE > 0x06010000
+ OCC_CATCH_SIGNALS;
+#endif
+ int iType, nbTypes [TopAbs_SHAPE];
+ for (iType = 0; iType < TopAbs_SHAPE; ++iType)
+ nbTypes[iType] = 0;
+ nbTypes[aShape.ShapeType()]++;
+
+ TopTools_MapOfShape aMapOfShape;
+ aMapOfShape.Add(aShape);
+ TopTools_ListOfShape aListOfShape;
+ aListOfShape.Append(aShape);
+
+ TopTools_ListIteratorOfListOfShape itL (aListOfShape);
+ for (; itL.More(); itL.Next()) {
+ TopoDS_Iterator it (itL.Value());
+ for (; it.More(); it.Next()) {
+ TopoDS_Shape s = it.Value();
+ if (aMapOfShape.Add(s)) {
+ aListOfShape.Append(s);
+ nbTypes[s.ShapeType()]++;
+ }
+ }
+ }
+
+ Astr = Astr + " VERTEX : " + TCollection_AsciiString(nbTypes[TopAbs_VERTEX]) + "\n";
+ Astr = Astr + " EDGE : " + TCollection_AsciiString(nbTypes[TopAbs_EDGE]) + "\n";
+ Astr = Astr + " WIRE : " + TCollection_AsciiString(nbTypes[TopAbs_WIRE]) + "\n";
+ Astr = Astr + " FACE : " + TCollection_AsciiString(nbTypes[TopAbs_FACE]) + "\n";
+ Astr = Astr + " SHELL : " + TCollection_AsciiString(nbTypes[TopAbs_SHELL]) + "\n";
+ Astr = Astr + " SOLID : " + TCollection_AsciiString(nbTypes[TopAbs_SOLID]) + "\n";
+ Astr = Astr + " COMPSOLID : " + TCollection_AsciiString(nbTypes[TopAbs_COMPSOLID]) + "\n";
+ Astr = Astr + " COMPOUND : " + TCollection_AsciiString(nbTypes[TopAbs_COMPOUND]) + "\n";
+ Astr = Astr + " SHAPE : " + TCollection_AsciiString(aMapOfShape.Extent());
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return Astr;
+ }
+
+ SetErrorCode(OK);
+ return Astr;
+}
+
+
+//=======================================================================
+//function : CheckSingularCase
+//purpose : auxilary for GetMinDistance()
+// workaround for bugs 19899, 19908 and 19910 from Mantis
+//=======================================================================
+static double CheckSingularCase(const TopoDS_Shape& aSh1,
+ const TopoDS_Shape& aSh2,
+ gp_Pnt& Ptmp1, gp_Pnt& Ptmp2)
+{
+ bool IsChange1 = false;
+ double AddDist1 = 0.0;
+ TopExp_Explorer anExp;
+ TopoDS_Shape tmpSh1, tmpSh2;
+ int nbf = 0;
+ for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
+ nbf++;
+ tmpSh1 = anExp.Current();
+ }
+ if(nbf==1) {
+ TopoDS_Shape sh = aSh1;
+ while(sh.ShapeType()==TopAbs_COMPOUND) {
+ TopoDS_Iterator it(sh);
+ sh = it.Value();
+ }
+ Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
+ if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
+ S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
+ if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
+ // non solid case
+ double U1,U2,V1,V2;
+ // changes for 0020677: EDF 1219 GEOM: MinDistance gives 0 instead of 20.88
+ //S->Bounds(U1,U2,V1,V2); changed by
+ ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh1),U1,U2,V1,V2);
+ // end of changes for 020677 (dmv)
+ Handle(Geom_RectangularTrimmedSurface) TrS1 =
+ new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
+ Handle(Geom_RectangularTrimmedSurface) TrS2 =
+ new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
+ BRep_Builder B;
+ TopoDS_Face F1,F2;
+ TopoDS_Compound Comp;
+ B.MakeCompound(Comp);
+ B.MakeFace(F1,TrS1,1.e-7);
+ B.Add(Comp,F1);
+ B.MakeFace(F2,TrS2,1.e-7);
+ B.Add(Comp,F2);
+ Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
+ sfs->Init(Comp);
+ sfs->SetPrecision(1.e-6);
+ sfs->SetMaxTolerance(1.0);
+ sfs->Perform();
+ tmpSh1 = sfs->Shape();
+ IsChange1 = true;
+ }
+ else {
+ if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
+ Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
+ gp_Pnt PC = SS->Location();
+ BRep_Builder B;
+ TopoDS_Vertex V;
+ B.MakeVertex(V,PC,1.e-7);
+ tmpSh1 = V;
+ AddDist1 = SS->Radius();
+ IsChange1 = true;
+ }
+ else {
+ Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
+ gp_Ax3 ax3 = TS->Position();
+ Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
+ BRep_Builder B;
+ TopoDS_Edge E;
+ B.MakeEdge(E,C,1.e-7);
+ tmpSh1 = E;
+ AddDist1 = TS->MinorRadius();
+ IsChange1 = true;
+ }
+ }
+ }
+ else
+ tmpSh1 = aSh1;
+ }
+ else
+ tmpSh1 = aSh1;
+ bool IsChange2 = false;
+ double AddDist2 = 0.0;
+ nbf = 0;
+ for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
+ nbf++;
+ tmpSh2 = anExp.Current();
+ }
+ if(nbf==1) {
+ TopoDS_Shape sh = aSh2;
+ while(sh.ShapeType()==TopAbs_COMPOUND) {
+ TopoDS_Iterator it(sh);
+ sh = it.Value();
+ }
+ Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
+ if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
+ S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
+ if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
+ // non solid case
+ double U1,U2,V1,V2;
+ //S->Bounds(U1,U2,V1,V2);
+ ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh2),U1,U2,V1,V2);
+ Handle(Geom_RectangularTrimmedSurface) TrS1 =
+ new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
+ Handle(Geom_RectangularTrimmedSurface) TrS2 =
+ new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
+ BRep_Builder B;
+ TopoDS_Face F1,F2;
+ TopoDS_Compound Comp;
+ B.MakeCompound(Comp);
+ B.MakeFace(F1,TrS1,1.e-7);
+ B.Add(Comp,F1);
+ B.MakeFace(F2,TrS2,1.e-7);
+ B.Add(Comp,F2);
+ Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
+ sfs->Init(Comp);
+ sfs->SetPrecision(1.e-6);
+ sfs->SetMaxTolerance(1.0);
+ sfs->Perform();
+ tmpSh2 = sfs->Shape();
+ IsChange2 = true;
+ }
+ else {
+ if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
+ Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
+ gp_Pnt PC = SS->Location();
+ BRep_Builder B;
+ TopoDS_Vertex V;
+ B.MakeVertex(V,PC,1.e-7);
+ tmpSh2 = V;
+ AddDist2 = SS->Radius();
+ IsChange2 = true;
+ }
+ else if( S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
+ Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
+ gp_Ax3 ax3 = TS->Position();
+ Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
+ BRep_Builder B;
+ TopoDS_Edge E;
+ B.MakeEdge(E,C,1.e-7);
+ tmpSh2 = E;
+ AddDist2 = TS->MinorRadius();
+ IsChange2 = true;
+ }
+ }
+ }
+ else
+ tmpSh2 = aSh2;
+ }
+ else
+ tmpSh2 = aSh2;
+
+ if( !IsChange1 && !IsChange2 )
+ return -2.0;
+
+ BRepExtrema_DistShapeShape dst(tmpSh1,tmpSh2);
+ if (dst.IsDone()) {
+ double MinDist = 1.e9;
+ gp_Pnt PMin1, PMin2, P1, P2;
+ for (int i = 1; i <= dst.NbSolution(); i++) {
+ P1 = dst.PointOnShape1(i);
+ P2 = dst.PointOnShape2(i);
+ Standard_Real Dist = P1.Distance(P2);
+ if (MinDist > Dist) {
+ MinDist = Dist;
+ PMin1 = P1;
+ PMin2 = P2;
+ }
+ }
+ if(MinDist<1.e-7) {
+ Ptmp1 = PMin1;
+ Ptmp2 = PMin2;
+ }
+ else {
+ gp_Dir aDir(gp_Vec(PMin1,PMin2));
+ if( MinDist > (AddDist1+AddDist2) ) {
+ Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
+ PMin1.Y() + aDir.Y()*AddDist1,
+ PMin1.Z() + aDir.Z()*AddDist1 );
+ Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
+ PMin2.Y() - aDir.Y()*AddDist2,
+ PMin2.Z() - aDir.Z()*AddDist2 );
+ return (MinDist - AddDist1 - AddDist2);
+ }
+ else {
+ if( AddDist1 > 0 ) {
+ Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
+ PMin1.Y() + aDir.Y()*AddDist1,
+ PMin1.Z() + aDir.Z()*AddDist1 );
+ Ptmp2 = Ptmp1;
+ }
+ else {
+ Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
+ PMin2.Y() - aDir.Y()*AddDist2,
+ PMin2.Z() - aDir.Z()*AddDist2 );
+ Ptmp1 = Ptmp2;
+ }
+ }
+ }
+ double res = MinDist - AddDist1 - AddDist2;
+ if(res<0.) res = 0.0;
+ return res;
+ }
+ return -2.0;
+}
+/* old variant
+static bool CheckSingularCase(const TopoDS_Shape& aSh1,
+ const TopoDS_Shape& aSh2,
+ gp_Pnt& Ptmp)
+{
+ TopExp_Explorer anExp;
+ TopoDS_Shape tmpSh1, tmpSh2;
+ int nbf = 0;
+ for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
+ nbf++;
+ tmpSh1 = anExp.Current();
+ }
+ if(nbf==1) {
+ Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
+ if( S1->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
+ S1->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
+ nbf = 0;
+ for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
+ nbf++;
+ tmpSh2 = anExp.Current();
+ Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
+ GeomAPI_IntSS ISS(S1,S2,1.e-7);
+ if(ISS.IsDone()) {
+ for(int i=1; i<=ISS.NbLines(); i++) {
+ Handle(Geom_Curve) C3d = ISS.Line(i);
+ BRep_Builder B;
+ TopoDS_Edge E;
+ B.MakeEdge(E,C3d,1.e-7);
+ BRepExtrema_DistShapeShape dst(tmpSh2,E);
+ if (dst.IsDone()) {
+ gp_Pnt PMin1, PMin2, P1, P2;
+ double MinDist = 1.e9;
+ for (int i = 1; i <= dst.NbSolution(); i++) {
+ P1 = dst.PointOnShape1(i);
+ P2 = dst.PointOnShape2(i);
+ Standard_Real Dist = P1.Distance(P2);
+ if (MinDist > Dist) {
+ MinDist = Dist;
+ Ptmp = P1;
+ }
+ }
+ if(MinDist<1.e-7)
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ nbf = 0;
+ for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
+ nbf++;
+ tmpSh1 = anExp.Current();
+ }
+ if(nbf==1) {
+ Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
+ if( S1->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
+ S1->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
+ nbf = 0;
+ for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
+ nbf++;
+ tmpSh2 = anExp.Current();
+ Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
+ GeomAPI_IntSS ISS(S1,S2,1.e-7);
+ if(ISS.IsDone()) {
+ for(int i=1; i<=ISS.NbLines(); i++) {
+ Handle(Geom_Curve) C3d = ISS.Line(i);
+ BRep_Builder B;
+ TopoDS_Edge E;
+ B.MakeEdge(E,C3d,1.e-7);
+ BRepExtrema_DistShapeShape dst(tmpSh2,E);
+ if (dst.IsDone()) {
+ gp_Pnt P1,P2;
+ double MinDist = 1.e9;
+ for (int i = 1; i <= dst.NbSolution(); i++) {
+ P1 = dst.PointOnShape1(i);
+ P2 = dst.PointOnShape2(i);
+ Standard_Real Dist = P1.Distance(P2);
+ if (MinDist > Dist) {
+ MinDist = Dist;
+ Ptmp = P1;
+ }
+ }
+ if(MinDist<1.e-7)
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+*/
+
+
+//=============================================================================
+/*!
+ * AreCoordsInside
+ */
+//=============================================================================
+std::vector<bool> GEOMImpl_IMeasureOperations::AreCoordsInside(Handle(GEOM_Object) theShape,
+ const std::vector<double>& coords,
+ double tolerance)
+{
+ std::vector<bool> res;
+ if (!theShape.IsNull()) {
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (!aRefShape.IsNull()) {
+ TopoDS_Shape aShape = aRefShape->GetValue();
+ if (!aShape.IsNull()) {
+ BRepClass3d_SolidClassifier SC(aShape);
+ unsigned int nb_points = coords.size()/3;
+ for (int i = 0; i < nb_points; i++) {
+ double x = coords[3*i];
+ double y = coords[3*i+1];
+ double z = coords[3*i+2];
+ gp_Pnt aPnt(x, y, z);
+ SC.Perform(aPnt, tolerance);
+ res.push_back( ( SC.State() == TopAbs_IN ) || ( SC.State() == TopAbs_ON ) );
+ }
+ }
+ }
+ }
+ return res;
+}
+
+//=============================================================================
+/*!
+ * GetMinDistance
+ */
+//=============================================================================
+Standard_Real GEOMImpl_IMeasureOperations::GetMinDistance
+ (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2,
+ Standard_Real& X1, Standard_Real& Y1, Standard_Real& Z1,
+ Standard_Real& X2, Standard_Real& Y2, Standard_Real& Z2)
+{
+ SetErrorCode(KO);
+ Standard_Real MinDist = 1.e9;
+
+ if (theShape1.IsNull() || theShape2.IsNull()) return MinDist;
+
+ Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction();
+ Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction();
+ if (aRefShape1.IsNull() || aRefShape2.IsNull()) return MinDist;
+
+ TopoDS_Shape aShape1 = aRefShape1->GetValue();
+ TopoDS_Shape aShape2 = aRefShape2->GetValue();
+ if (aShape1.IsNull() || aShape2.IsNull()) {
+ SetErrorCode("One of Objects has NULL Shape");
+ return MinDist;
+ }
+
+ //Compute the parameters
+ try {
+#if OCC_VERSION_LARGE > 0x06010000
+ OCC_CATCH_SIGNALS;
+#endif
+
+ // Issue 0020231: A min distance bug with torus and vertex.
+ // Make GetMinDistance() return zero if a sole VERTEX is inside any of SOLIDs
+
+ // which of shapes consists of only one vertex?
+ TopExp_Explorer exp1(aShape1,TopAbs_VERTEX), exp2(aShape2,TopAbs_VERTEX);
+ TopoDS_Shape V1 = exp1.More() ? exp1.Current() : TopoDS_Shape();
+ TopoDS_Shape V2 = exp2.More() ? exp2.Current() : TopoDS_Shape();
+ exp1.Next(); exp2.Next();
+ if ( exp1.More() ) V1.Nullify();
+ if ( exp2.More() ) V2.Nullify();
+ // vertex and container of solids
+ TopoDS_Shape V = V1.IsNull() ? V2 : V1;
+ TopoDS_Shape S = V1.IsNull() ? aShape1 : aShape2;
+ if ( !V.IsNull() ) {
+ // classify vertex against solids
+ gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( V ) );
+ for ( exp1.Init( S, TopAbs_SOLID ); exp1.More(); exp1.Next() ) {
+ BRepClass3d_SolidClassifier classifier( exp1.Current(), p, 1e-6);
+ if ( classifier.State() == TopAbs_IN ) {
+ p.Coord(X1, Y1, Z1);
+ p.Coord(X2, Y2, Z2);
+ SetErrorCode(OK);
+ return 0.0;
+ }
+ }
+ }
+ // End Issue 0020231
+
+ // skl 30.06.2008
+ // additional workaround for bugs 19899, 19908 and 19910 from Mantis
+ gp_Pnt Ptmp1, Ptmp2;
+ double dist = CheckSingularCase(aShape1, aShape2, Ptmp1, Ptmp2);
+ if(dist>-1.0) {
+ Ptmp1.Coord(X1, Y1, Z1);
+ Ptmp2.Coord(X2, Y2, Z2);
+ SetErrorCode(OK);
+ return dist;
+ }
+
+ BRepExtrema_DistShapeShape dst (aShape1, aShape2);
+ if (dst.IsDone()) {
+ gp_Pnt PMin1, PMin2, P1, P2;
+
+ for (int i = 1; i <= dst.NbSolution(); i++) {
+ P1 = dst.PointOnShape1(i);
+ P2 = dst.PointOnShape2(i);
+
+ Standard_Real Dist = P1.Distance(P2);
+ if (MinDist > Dist) {
+ MinDist = Dist;
+ PMin1 = P1;
+ PMin2 = P2;
+ }
+ }
+
+ PMin1.Coord(X1, Y1, Z1);
+ PMin2.Coord(X2, Y2, Z2);
+ }
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return MinDist;
+ }
+
+ SetErrorCode(OK);
+ return MinDist;
+}
+
+//=======================================================================
+/*!
+ * Get coordinates of point
+ */
+//=======================================================================
+void GEOMImpl_IMeasureOperations::PointCoordinates (Handle(GEOM_Object) theShape,
+ Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull())
+ return;
+
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (aRefShape.IsNull())
+ return;
+
+ TopoDS_Shape aShape = aRefShape->GetValue();
+ if (aShape.IsNull() || aShape.ShapeType() != TopAbs_VERTEX)
+ {
+ SetErrorCode( "Shape must be a vertex" );
+ return;
+ }
+
+ try {
+#if OCC_VERSION_LARGE > 0x06010000
+ OCC_CATCH_SIGNALS;
+#endif
+ gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
+ theX = aPnt.X();
+ theY = aPnt.Y();
+ theZ = aPnt.Z();
+
+ SetErrorCode(OK);
+ }
+ catch (Standard_Failure)
+ {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode( aFail->GetMessageString() );
+ }
+}
+
+//=======================================================================
+/*!
+ * Compute angle (in degrees) between two lines
+ */
+//=======================================================================
+Standard_Real GEOMImpl_IMeasureOperations::GetAngle (Handle(GEOM_Object) theLine1,
+ Handle(GEOM_Object) theLine2)
+{
+ if (theLine1->GetType() == GEOM_VECTOR &&
+ theLine2->GetType() == GEOM_VECTOR)
+ return GetAngleBtwVectors(theLine1, theLine2);
+
+ SetErrorCode(KO);
+
+ Standard_Real anAngle = -1.0;
+
+ if (theLine1.IsNull() || theLine2.IsNull())
+ return anAngle;
+
+ Handle(GEOM_Function) aRefLine1 = theLine1->GetLastFunction();
+ Handle(GEOM_Function) aRefLine2 = theLine2->GetLastFunction();
+ if (aRefLine1.IsNull() || aRefLine2.IsNull())
+ return anAngle;
+
+ TopoDS_Shape aLine1 = aRefLine1->GetValue();
+ TopoDS_Shape aLine2 = aRefLine2->GetValue();
+ if (aLine1.IsNull() || aLine2.IsNull() ||
+ aLine1.ShapeType() != TopAbs_EDGE ||
+ aLine2.ShapeType() != TopAbs_EDGE)
+ {
+ SetErrorCode("Two edges must be given");
+ return anAngle;
+ }
+
+ try {
+#if OCC_VERSION_LARGE > 0x06010000
+ OCC_CATCH_SIGNALS;
+#endif
+ TopoDS_Edge E1 = TopoDS::Edge(aLine1);
+ TopoDS_Edge E2 = TopoDS::Edge(aLine2);
+
+ double fp,lp;
+ Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
+ Handle(Geom_Curve) C2 = BRep_Tool::Curve(E2,fp,lp);
+
+ if ( C1.IsNull() || C2.IsNull() ||
+ !C1->IsKind(STANDARD_TYPE(Geom_Line)) ||
+ !C2->IsKind(STANDARD_TYPE(Geom_Line)))
+ {
+ SetErrorCode("The edges must be linear");
+ return anAngle;
+ }
+
+ Handle(Geom_Line) L1 = Handle(Geom_Line)::DownCast(C1);
+ Handle(Geom_Line) L2 = Handle(Geom_Line)::DownCast(C2);
+
+ gp_Lin aLin1 = L1->Lin();
+ gp_Lin aLin2 = L2->Lin();
+
+ anAngle = aLin1.Angle(aLin2);
+ anAngle /= PI180; // convert radians into degrees
+
+ if (anAngle > 90.0) {
+ anAngle = 180.0 - anAngle;
+ }
+
+ SetErrorCode(OK);
+ }
+ catch (Standard_Failure)
+ {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ }
+
+ return anAngle;
+}
+
+//=======================================================================
+/*!
+ * Compute angle (in degrees) between two vectors
+ */
+//=======================================================================
+Standard_Real GEOMImpl_IMeasureOperations::GetAngleBtwVectors (Handle(GEOM_Object) theVec1,
+ Handle(GEOM_Object) theVec2)
+{
+ SetErrorCode(KO);
+
+ Standard_Real anAngle = -1.0;
+
+ if (theVec1.IsNull() || theVec2.IsNull())
+ return anAngle;
+
+ Handle(GEOM_Function) aRefVec1 = theVec1->GetLastFunction();
+ Handle(GEOM_Function) aRefVec2 = theVec2->GetLastFunction();
+ if (aRefVec1.IsNull() || aRefVec2.IsNull())
+ return anAngle;
+
+ TopoDS_Shape aVec1 = aRefVec1->GetValue();
+ TopoDS_Shape aVec2 = aRefVec2->GetValue();
+ if (aVec1.IsNull() || aVec2.IsNull() ||
+ aVec1.ShapeType() != TopAbs_EDGE ||
+ aVec2.ShapeType() != TopAbs_EDGE)
+ {
+ SetErrorCode("Two edges must be given");
+ return anAngle;
+ }
+