-// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
//
-// This library is distributed in the hope that it will be useful
+// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
-#include <Standard_Stream.hxx>
-
#include <GEOMImpl_IMeasureOperations.hxx>
-
-#include <GEOMImpl_Types.hxx>
-#include <GEOMImpl_MeasureDriver.hxx>
#include <GEOMImpl_IMeasure.hxx>
+#include <GEOMImpl_MeasureDriver.hxx>
+#include <GEOMImpl_Types.hxx>
+
+#include <GEOMUtils.hxx>
-#include <GEOMAlgo_ShapeInfo.hxx>
+#include <GEOMAlgo_AlgoTools.hxx>
+#include <GEOMAlgo_KindOfName.hxx>
#include <GEOMAlgo_ShapeInfoFiller.hxx>
-#include <GEOM_Function.hxx>
#include <GEOM_PythonDump.hxx>
#include <utilities.h>
-#include <OpUtil.hxx>
-#include <Utils_ExceptHandlers.hxx>
// OCCT Includes
-#include <TFunction_DriverTable.hxx>
-#include <TFunction_Driver.hxx>
-#include <TFunction_Logbook.hxx>
-#include <TDF_Tool.hxx>
-
-#include <BRep_Tool.hxx>
-#include <BRepAdaptor_Surface.hxx>
+#include <Bnd_Box.hxx>
+#include <BOPAlgo_CheckerSI.hxx>
+#include <BOPCol_ListOfShape.hxx>
+#include <BOPDS_DS.hxx>
+#include <BOPDS_MapOfPassKey.hxx>
#include <BRepBndLib.hxx>
-#include <BRepCheck.hxx>
-#include <BRepCheck_Result.hxx>
+#include <BRepBuilderAPI_Copy.hxx>
#include <BRepCheck_ListIteratorOfListOfStatus.hxx>
+#include <BRepCheck_Shell.hxx>
+#include <BRepClass3d_SolidClassifier.hxx>
+#include <BRepClass_FaceClassifier.hxx>
#include <BRepExtrema_DistShapeShape.hxx>
#include <BRepGProp.hxx>
#include <BRepTools.hxx>
-
-#include <Bnd_Box.hxx>
-
+#include <BRep_Tool.hxx>
+#include <Geom_Line.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx>
+#include <GeomAPI_ProjectPointOnSurf.hxx>
+#include <GeomLProp_CLProps.hxx>
+#include <GeomLProp_SLProps.hxx>
#include <GProp_GProps.hxx>
#include <GProp_PrincipalProps.hxx>
-
-#include <TopAbs.hxx>
+#include <ShapeAnalysis.hxx>
+#include <ShapeAnalysis_Surface.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Shape.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopoDS_Iterator.hxx>
-#include <TopExp_Explorer.hxx>
-#include <TopTools_MapOfShape.hxx>
-#include <TopTools_ListOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfIntegerListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
-
-#include <GeomAbs_SurfaceType.hxx>
-#include <Geom_Surface.hxx>
-#include <Geom_Plane.hxx>
-#include <Geom_SphericalSurface.hxx>
-#include <Geom_CylindricalSurface.hxx>
-#include <Geom_ToroidalSurface.hxx>
-#include <Geom_ConicalSurface.hxx>
-#include <Geom_SurfaceOfLinearExtrusion.hxx>
-#include <Geom_SurfaceOfRevolution.hxx>
-#include <Geom_BezierSurface.hxx>
-#include <Geom_BSplineSurface.hxx>
-#include <Geom_RectangularTrimmedSurface.hxx>
-#include <Geom_OffsetSurface.hxx>
-#include <Geom_Line.hxx>
-
-#include <gp_Pln.hxx>
-#include <gp_Lin.hxx>
-
-#include <Standard_Failure.hxx>
+#include <TopTools_ListOfShape.hxx>
#include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
//=============================================================================
TopoDS_Shape aShape = aRefShape->GetValue();
if (aShape.IsNull()) return aKind;
+ int geom_type = theShape->GetType();
+
+ // check if it's advanced shape
+ if ( geom_type > USER_TYPE ) {
+ SetErrorCode(OK);
+ return SK_ADVANCED;
+ }
+
// Call algorithm
GEOMAlgo_ShapeInfoFiller aSF;
aSF.SetShape(aShape);
return aKind;
}
-//=============================================================================
-/*! Get LCS, corresponding to the given shape.
- * Origin of the LCS is situated at the shape's center of mass.
- * Axes of the LCS are obtained from shape's location or,
- * if the shape is a planar face, from position of its plane.
- */
-//=============================================================================
-gp_Ax3 GEOMImpl_IMeasureOperations::GetPosition (const TopoDS_Shape& theShape)
-{
- gp_Ax3 aResult;
-
- if (theShape.IsNull())
- return aResult;
-
- // Axes
- aResult.Transform(theShape.Location().Transformation());
- if (theShape.ShapeType() == TopAbs_FACE) {
- Handle(Geom_Surface) aGS = BRep_Tool::Surface(TopoDS::Face(theShape));
- if (!aGS.IsNull() && aGS->IsKind(STANDARD_TYPE(Geom_Plane))) {
- Handle(Geom_Plane) aGPlane = Handle(Geom_Plane)::DownCast(aGS);
- gp_Pln aPln = aGPlane->Pln();
- aResult = aPln.Position();
- }
- }
-
- // Origin
- gp_Pnt aPnt;
- if (theShape.ShapeType() == TopAbs_VERTEX) {
- aPnt = BRep_Tool::Pnt(TopoDS::Vertex(theShape));
- }
- else {
- GProp_GProps aSystem;
- if (theShape.ShapeType() == TopAbs_EDGE || theShape.ShapeType() == TopAbs_WIRE)
- BRepGProp::LinearProperties(theShape, aSystem);
- else if (theShape.ShapeType() == TopAbs_FACE || theShape.ShapeType() == TopAbs_SHELL)
- BRepGProp::SurfaceProperties(theShape, aSystem);
- else
- BRepGProp::VolumeProperties(theShape, aSystem);
-
- aPnt = aSystem.CentreOfMass();
- }
-
- aResult.SetLocation(aPnt);
-
- return aResult;
-}
-
//=============================================================================
/*!
* GetPosition
}
try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
-#endif
- gp_Ax3 anAx3 = GetPosition(aShape);
+ gp_Ax3 anAx3 = GEOMUtils::GetPosition(aShape);
gp_Pnt anOri = anAx3.Location();
gp_Dir aDirZ = anAx3.Direction();
//Compute the CentreOfMass value
try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
-#endif
if (!GetSolver()->ComputeFunction(aFunction)) {
SetErrorCode("Measure driver failed to compute centre of mass");
return NULL;
return aCDG;
}
+//=============================================================================
+/*!
+ * GetVertexByIndex
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetVertexByIndex
+ (Handle(GEOM_Object) theShape,
+ Standard_Integer theIndex)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull()) return NULL;
+
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (aRefShape.IsNull()) return NULL;
+
+ //Add a new Vertex object
+ Handle(GEOM_Object) aVertex = GetEngine()->AddObject(GetDocID(), GEOM_POINT);
+
+ //Add a function
+ Handle(GEOM_Function) aFunction =
+ aVertex->AddFunction(GEOMImpl_MeasureDriver::GetID(), VERTEX_BY_INDEX);
+ if (aFunction.IsNull()) return NULL;
+
+ //Check if the function is set correctly
+ if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
+
+ GEOMImpl_IMeasure aCI (aFunction);
+ aCI.SetBase(aRefShape);
+ aCI.SetIndex(theIndex);
+
+ //Compute
+ try {
+ OCC_CATCH_SIGNALS;
+ if (!GetSolver()->ComputeFunction(aFunction)) {
+ SetErrorCode("Vertex by index driver failed.");
+ return NULL;
+ }
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return NULL;
+ }
+
+ //Make a Python command
+ GEOM::TPythonDump(aFunction) << aVertex << " = geompy.GetVertexByIndex(" << theShape << ", " << theIndex << ")";
+
+ SetErrorCode(OK);
+ return aVertex;
+}
+
//=============================================================================
/*!
* GetNormal
//Compute the Normale value
try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
-#endif
if (!GetSolver()->ComputeFunction(aFunction)) {
SetErrorCode("Measure driver failed to compute normake of face");
return NULL;
//Compute the parameters
GProp_GProps LProps, SProps;
try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
-#endif
BRepGProp::LinearProperties(aShape, LProps);
theLength = LProps.Mass();
theVolume = 0.0;
if (aShape.ShapeType() < TopAbs_SHELL) {
for (TopExp_Explorer Exp (aShape, TopAbs_SOLID); Exp.More(); Exp.Next()) {
- GProp_GProps VProps;
- BRepGProp::VolumeProperties(Exp.Current(), VProps);
- theVolume += VProps.Mass();
+ GProp_GProps VProps;
+ BRepGProp::VolumeProperties(Exp.Current(), VProps);
+ theVolume += VProps.Mass();
}
}
}
GProp_GProps System;
try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
-#endif
if (aShape.ShapeType() == TopAbs_VERTEX ||
aShape.ShapeType() == TopAbs_EDGE ||
aShape.ShapeType() == TopAbs_WIRE) {
//=============================================================================
void GEOMImpl_IMeasureOperations::GetBoundingBox
(Handle(GEOM_Object) theShape,
+ const Standard_Boolean precise,
Standard_Real& Xmin, Standard_Real& Xmax,
Standard_Real& Ymin, Standard_Real& Ymax,
Standard_Real& Zmin, Standard_Real& Zmax)
Bnd_Box B;
try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
-#endif
+ BRepBuilderAPI_Copy aCopyTool (aShape);
+ if (!aCopyTool.IsDone()) {
+ SetErrorCode("GetBoundingBox Error: Bad shape detected");
+ return;
+ }
+
+ aShape = aCopyTool.Shape();
+
+ // remove triangulation to obtain more exact boundaries
+ BRepTools::Clean(aShape);
+
BRepBndLib::Add(aShape, B);
+
+ if (precise) {
+ if (!GEOMUtils::PreciseBoundingBox(aShape, B)) {
+ SetErrorCode("GetBoundingBox Error: Bounding box cannot be precised");
+ return;
+ }
+ }
+
B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
}
catch (Standard_Failure) {
SetErrorCode(OK);
}
+//=============================================================================
+/*!
+ * GetBoundingBox
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetBoundingBox
+ (Handle(GEOM_Object) theShape,
+ const Standard_Boolean precise)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull()) return NULL;
+
+ //Add a new BoundingBox object
+ Handle(GEOM_Object) aBnd = GetEngine()->AddObject(GetDocID(), GEOM_BOX);
+
+ //Add a new BoundingBox function
+ const int aType = (precise ? BND_BOX_MEASURE_PRECISE : BND_BOX_MEASURE);
+ Handle(GEOM_Function) aFunction =
+ aBnd->AddFunction(GEOMImpl_MeasureDriver::GetID(), aType);
+ if (aFunction.IsNull()) return NULL;
+
+ //Check if the function is set correctly
+ if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
+
+ GEOMImpl_IMeasure aCI (aFunction);
+
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (aRefShape.IsNull()) return NULL;
+
+ aCI.SetBase(aRefShape);
+
+ //Compute the BoundingBox value
+ try {
+ OCC_CATCH_SIGNALS;
+ if (!GetSolver()->ComputeFunction(aFunction)) {
+ SetErrorCode("Measure driver failed to compute a bounding box");
+ return NULL;
+ }
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return NULL;
+ }
+
+ //Make a Python command
+ GEOM::TPythonDump aPd(aFunction);
+
+ aPd << aBnd << " = geompy.MakeBoundingBox(" << theShape;
+
+ if (precise) {
+ aPd << ", True";
+ }
+
+ aPd << ")";
+
+ SetErrorCode(OK);
+ return aBnd;
+}
+
//=============================================================================
/*!
* GetTolerance
FaceMax = EdgeMax = VertMax = -RealLast();
try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
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;
+ FaceMax = T;
if (T < FaceMin)
- FaceMin = T;
+ 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;
+ EdgeMax = T;
if (T < EdgeMin)
- EdgeMin = T;
+ 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;
+ VertMax = T;
if (T < VertMin)
- VertMin = T;
+ VertMin = T;
}
}
catch (Standard_Failure) {
* CheckShape
*/
//=============================================================================
-bool GEOMImpl_IMeasureOperations::CheckShape (Handle(GEOM_Object) theShape,
- const Standard_Boolean theIsCheckGeom,
- TCollection_AsciiString& theDump)
+bool GEOMImpl_IMeasureOperations::CheckShape (Handle(GEOM_Object) theShape,
+ const Standard_Boolean theIsCheckGeom,
+ std::list<ShapeError> &theErrors)
{
SetErrorCode(KO);
+ theErrors.clear();
if (theShape.IsNull()) return false;
//Compute the parameters
bool isValid = false;
try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
-#endif
BRepCheck_Analyzer ana (aShape, theIsCheckGeom);
if (ana.IsValid()) {
- theDump.Clear();
isValid = true;
} else {
- StructuralDump(ana, aShape, theDump);
+ FillErrors(ana, aShape, theErrors);
}
}
catch (Standard_Failure) {
//=============================================================================
/*!
- * WhatIs
+ * PrintShapeErrors
*/
//=============================================================================
-TCollection_AsciiString GEOMImpl_IMeasureOperations::WhatIs (Handle(GEOM_Object) theShape)
+TCollection_AsciiString GEOMImpl_IMeasureOperations::PrintShapeErrors
+ (Handle(GEOM_Object) theShape,
+ const std::list<ShapeError> &theErrors)
{
- SetErrorCode(KO);
+ TCollection_AsciiString aDump;
- TCollection_AsciiString Astr;
-
- if (theShape.IsNull()) return Astr;
+ if (theShape.IsNull()) {
+ return aDump;
+ }
Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
- if (aRefShape.IsNull()) return Astr;
+
+ if (aRefShape.IsNull()) {
+ return aDump;
+ }
TopoDS_Shape aShape = aRefShape->GetValue();
+
if (aShape.IsNull()) {
SetErrorCode("The Objects has NULL Shape");
- return Astr;
+ return aDump;
}
- //Compute the parameters
- if (aShape.ShapeType() == TopAbs_EDGE) {
- if (BRep_Tool::Degenerated(TopoDS::Edge(aShape))) {
- Astr = Astr + " It is a degenerated edge \n";
- }
- }
+ if (!theErrors.empty()) {
+ // The shape is not valid. Prepare errors for dump.
+ TopTools_IndexedMapOfShape anIndices;
+ std::list<ShapeError>::const_iterator anIter = theErrors.begin();
+ Standard_Integer nbv, nbe, nbw, nbf, nbs, nbo;
+ nbv = nbe = nbw = nbf = nbs = nbo = 0;
- Astr = Astr + " Number of sub-shapes : \n";
+ // Map sub-shapes and their indices
+ TopExp::MapShapes(aShape, anIndices);
- try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
- OCC_CATCH_SIGNALS;
-#endif
- int iType, nbTypes [TopAbs_SHAPE];
- for (iType = 0; iType < TopAbs_SHAPE; ++iType)
- nbTypes[iType] = 0;
- nbTypes[aShape.ShapeType()]++;
+ const Standard_Integer aNbSubShapes = anIndices.Extent();
+ TColStd_MapOfInteger aMapPbInd;
- TopTools_MapOfShape aMapOfShape;
- aMapOfShape.Add(aShape);
- TopTools_ListOfShape aListOfShape;
- aListOfShape.Append(aShape);
+ aDump += " -- The Shape has problems :\n";
+ aDump += " Check Count\n";
+ aDump += " ------------------------------------------------\n";
- 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()]++;
+ for (; anIter != theErrors.end(); anIter++) {
+ Standard_Integer aNbShapes = anIter->incriminated.size();
+
+ switch(anIter->error) {
+ case BRepCheck_InvalidPointOnCurve:
+ aDump += " Invalid Point on Curve ................... ";
+ break;
+ case BRepCheck_InvalidPointOnCurveOnSurface:
+ aDump += " Invalid Point on CurveOnSurface .......... ";
+ break;
+ case BRepCheck_InvalidPointOnSurface:
+ aDump += " Invalid Point on Surface ................. ";
+ break;
+ case BRepCheck_No3DCurve:
+ aDump += " No 3D Curve .............................. ";
+ break;
+ case BRepCheck_Multiple3DCurve:
+ aDump += " Multiple 3D Curve ........................ ";
+ break;
+ case BRepCheck_Invalid3DCurve:
+ aDump += " Invalid 3D Curve ......................... ";
+ break;
+ case BRepCheck_NoCurveOnSurface:
+ aDump += " No Curve on Surface ...................... ";
+ break;
+ case BRepCheck_InvalidCurveOnSurface:
+ aDump += " Invalid Curve on Surface ................. ";
+ break;
+ case BRepCheck_InvalidCurveOnClosedSurface:
+ aDump += " Invalid Curve on closed Surface .......... ";
+ break;
+ case BRepCheck_InvalidSameRangeFlag:
+ aDump += " Invalid SameRange Flag ................... ";
+ break;
+ case BRepCheck_InvalidSameParameterFlag:
+ aDump += " Invalid SameParameter Flag ............... ";
+ break;
+ case BRepCheck_InvalidDegeneratedFlag:
+ aDump += " Invalid Degenerated Flag ................. ";
+ break;
+ case BRepCheck_FreeEdge:
+ aDump += " Free Edge ................................ ";
+ break;
+ case BRepCheck_InvalidMultiConnexity:
+ aDump += " Invalid MultiConnexity ................... ";
+ break;
+ case BRepCheck_InvalidRange:
+ aDump += " Invalid Range ............................ ";
+ break;
+ case BRepCheck_EmptyWire:
+ aDump += " Empty Wire ............................... ";
+ break;
+ case BRepCheck_RedundantEdge:
+ aDump += " Redundant Edge ........................... ";
+ break;
+ case BRepCheck_SelfIntersectingWire:
+ aDump += " Self Intersecting Wire ................... ";
+ break;
+ case BRepCheck_NoSurface:
+ aDump += " No Surface ............................... ";
+ break;
+ case BRepCheck_InvalidWire:
+ aDump += " Invalid Wire ............................. ";
+ break;
+ case BRepCheck_RedundantWire:
+ aDump += " Redundant Wire ........................... ";
+ break;
+ case BRepCheck_IntersectingWires:
+ aDump += " Intersecting Wires ....................... ";
+ break;
+ case BRepCheck_InvalidImbricationOfWires:
+ aDump += " Invalid Imbrication of Wires ............. ";
+ break;
+ case BRepCheck_EmptyShell:
+ aDump += " Empty Shell .............................. ";
+ break;
+ case BRepCheck_RedundantFace:
+ aDump += " Redundant Face ........................... ";
+ break;
+ case BRepCheck_UnorientableShape:
+ aDump += " Unorientable Shape ....................... ";
+ break;
+ case BRepCheck_NotClosed:
+ aDump += " Not Closed ............................... ";
+ break;
+ case BRepCheck_NotConnected:
+ aDump += " Not Connected ............................ ";
+ break;
+ case BRepCheck_SubshapeNotInShape:
+ aDump += " Sub-shape not in Shape ................... ";
+ break;
+ case BRepCheck_BadOrientation:
+ aDump += " Bad Orientation .......................... ";
+ break;
+ case BRepCheck_BadOrientationOfSubshape:
+ aDump += " Bad Orientation of Sub-shape ............. ";
+ break;
+ case BRepCheck_InvalidToleranceValue:
+ aDump += " Invalid Tolerance Value .................. ";
+ break;
+ case BRepCheck_CheckFail:
+ aDump += " Check Shape Failure ...................... ";
+ break;
+ default:
+ break;
+ }
+
+ aDump += TCollection_AsciiString(aNbShapes) + "\n";
+
+ // Count types of shape.
+ std::list<int>::const_iterator aShIter = anIter->incriminated.begin();
+
+ for (; aShIter != anIter->incriminated.end(); aShIter++) {
+ const Standard_Integer anIndex = *aShIter;
+
+ if (anIndex > 0 && anIndex <= aNbSubShapes && aMapPbInd.Add(anIndex)) {
+ const TopoDS_Shape &aSubShape = anIndices.FindKey(anIndex);
+ const TopAbs_ShapeEnum aType = aSubShape.ShapeType();
+
+ switch (aType) {
+ case TopAbs_VERTEX : nbv++; break;
+ case TopAbs_EDGE : nbe++; break;
+ case TopAbs_WIRE : nbw++; break;
+ case TopAbs_FACE : nbf++; break;
+ case TopAbs_SHELL : nbs++; break;
+ case TopAbs_SOLID : nbo++; break;
+ default : break;
+ }
}
}
}
- 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;
+ const Standard_Integer aNbFaultyShapes = nbv + nbe + nbw + nbf + nbs + nbo;
+ aDump += " ------------------------------------------------\n";
+ aDump += "*** Shapes with problems : ";
+ aDump += TCollection_AsciiString(aNbFaultyShapes) + "\n";
+
+ if (nbv > 0) {
+ aDump += "VERTEX : ";
+ if (nbv < 10) aDump += " ";
+ aDump += TCollection_AsciiString(nbv) + "\n";
+ }
+ if (nbe > 0) {
+ aDump += "EDGE : ";
+ if (nbe < 10) aDump += " ";
+ aDump += TCollection_AsciiString(nbe) + "\n";
+ }
+ if (nbw > 0) {
+ aDump += "WIRE : ";
+ if (nbw < 10) aDump += " ";
+ aDump += TCollection_AsciiString(nbw) + "\n";
+ }
+ if (nbf > 0) {
+ aDump += "FACE : ";
+ if (nbf < 10) aDump += " ";
+ aDump += TCollection_AsciiString(nbf) + "\n";
+ }
+ if (nbs > 0) {
+ aDump += "SHELL : ";
+ if (nbs < 10) aDump += " ";
+ aDump += TCollection_AsciiString(nbs) + "\n";
+ }
+ if (nbo > 0) {
+ aDump += "SOLID : ";
+ if (nbo < 10) aDump += " ";
+ aDump += TCollection_AsciiString(nbo) + "\n";
+ }
}
- SetErrorCode(OK);
- return Astr;
+ return aDump;
}
//=============================================================================
/*!
- * GetMinDistance
+ * CheckSelfIntersections
*/
//=============================================================================
-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)
+bool GEOMImpl_IMeasureOperations::CheckSelfIntersections
+ (Handle(GEOM_Object) theShape,
+ Handle(TColStd_HSequenceOfInteger)& theIntersections)
{
SetErrorCode(KO);
- Standard_Real MinDist = 1.e9;
+ bool isGood = false;
- if (theShape1.IsNull() || theShape2.IsNull()) return MinDist;
+ if (theIntersections.IsNull())
+ theIntersections = new TColStd_HSequenceOfInteger;
+ else
+ theIntersections->Clear();
- Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction();
- Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction();
- if (aRefShape1.IsNull() || aRefShape2.IsNull()) return MinDist;
+ if (theShape.IsNull())
+ return isGood;
- TopoDS_Shape aShape1 = aRefShape1->GetValue();
- TopoDS_Shape aShape2 = aRefShape2->GetValue();
- if (aShape1.IsNull() || aShape2.IsNull()) {
- SetErrorCode("One of Objects has NULL Shape");
- return MinDist;
- }
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (aRefShape.IsNull()) return isGood;
- //Compute the parameters
- try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+ TopoDS_Shape aShape = aRefShape->GetValue();
+ if (aShape.IsNull()) return isGood;
+
+ // 0. Prepare data
+ TopoDS_Shape aScopy;
+ //
+ GEOMAlgo_AlgoTools::CopyShape(aShape, aScopy);
+ //
+ // Map sub-shapes and their indices
+ TopTools_IndexedMapOfShape anIndices;
+ TopExp::MapShapes(aScopy, anIndices);
+
+ BOPCol_ListOfShape aLCS;
+ aLCS.Append(aScopy);
+ //
+ BOPAlgo_CheckerSI aCSI; // checker of self-interferences
+ aCSI.SetArguments(aLCS);
+
+ // 1. Launch the checker
+ aCSI.Perform();
+ Standard_Integer iErr = aCSI.ErrorStatus();
+
+ isGood = true;
+ //
+ Standard_Integer aNbS, n1, n2;
+ BOPDS_MapIteratorMapOfPassKey aItMPK;
+ //
+ // 2. Take the shapes from DS
+ const BOPDS_DS& aDS = aCSI.DS();
+ aNbS=aDS.NbShapes();
+ //
+ // 3. Get the pairs of interfered shapes
+ const BOPDS_MapOfPassKey& aMPK=aDS.Interferences();
+ aItMPK.Initialize(aMPK);
+ for (; aItMPK.More(); aItMPK.Next()) {
+ const BOPDS_PassKey& aPK=aItMPK.Value();
+ aPK.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;
+ }
+
+ if (!iErr) {
+ 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 {
OCC_CATCH_SIGNALS;
-#endif
- BRepExtrema_DistShapeShape dst (aShape1, aShape2);
- if (dst.IsDone()) {
- gp_Pnt PMin1, PMin2, P1, P2;
+ int iType, nbTypes [TopAbs_SHAPE];
+ for (iType = 0; iType < TopAbs_SHAPE; ++iType)
+ nbTypes[iType] = 0;
+ nbTypes[aShape.ShapeType()]++;
- for (int i = 1; i <= dst.NbSolution(); i++) {
- P1 = dst.PointOnShape1(i);
- P2 = dst.PointOnShape2(i);
+ TopTools_MapOfShape aMapOfShape;
+ aMapOfShape.Add(aShape);
+ TopTools_ListOfShape aListOfShape;
+ aListOfShape.Append(aShape);
- Standard_Real Dist = P1.Distance(P2);
- if (MinDist > Dist) {
- MinDist = Dist;
- PMin1 = P1;
- PMin2 = P2;
+ 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;
+ }
- PMin1.Coord(X1, Y1, Z1);
- PMin2.Coord(X2, Y2, Z2);
+ SetErrorCode(OK);
+ return Astr;
+}
+
+//=============================================================================
+/*!
+ * AreCoordsInside
+ */
+//=============================================================================
+std::vector<bool>
+GEOMImpl_IMeasureOperations::AreCoordsInside(Handle(GEOM_Object) theShape,
+ const std::vector<double>& coords,
+ double tolerance)
+{
+ std::vector<bool> isInsideRes;
+ if (!theShape.IsNull()) {
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (!aRefShape.IsNull()) {
+ TopoDS_Shape aShape = aRefShape->GetValue();
+ if (!aShape.IsNull())
+ {
+ TopTools_IndexedMapOfShape mapShape;
+ {
+ TopExp_Explorer anExp;
+ for ( anExp.Init( aShape, TopAbs_SOLID ); anExp.More(); anExp.Next() )
+ mapShape.Add( anExp.Current() );
+ for ( anExp.Init( aShape, TopAbs_FACE, TopAbs_SOLID ); anExp.More(); anExp.Next() )
+ mapShape.Add( anExp.Current() );
+ for ( anExp.Init( aShape, TopAbs_EDGE, TopAbs_FACE ); anExp.More(); anExp.Next() )
+ mapShape.Add( anExp.Current() );
+ for ( anExp.Init( aShape, TopAbs_VERTEX, TopAbs_EDGE ); anExp.More(); anExp.Next() )
+ mapShape.Add( anExp.Current() ); //// ?????????
+ }
+ size_t nb_points = coords.size()/3, nb_points_inside = 0;
+ isInsideRes.resize( nb_points, false );
+
+ for ( int iS = 1; iS <= mapShape.Extent(); ++iS )
+ {
+ if ( nb_points_inside == nb_points )
+ break;
+ aShape = mapShape( iS );
+ switch ( aShape.ShapeType() ) {
+ case TopAbs_SOLID:
+ {
+ BRepClass3d_SolidClassifier SC( TopoDS::Solid( aShape ));
+ for ( size_t i = 0; i < nb_points; i++)
+ {
+ if ( isInsideRes[ i ]) continue;
+ gp_Pnt aPnt( coords[3*i], coords[3*i+1], coords[3*i+2] );
+ SC.Perform( aPnt, tolerance );
+ isInsideRes[ i ] = (( SC.State() == TopAbs_IN ) || ( SC.State() == TopAbs_ON ));
+ nb_points_inside += isInsideRes[ i ];
+ }
+ break;
+ }
+ case TopAbs_FACE:
+ {
+ Standard_Real u1,u2,v1,v2;
+ const TopoDS_Face& face = TopoDS::Face( aShape );
+ Handle(Geom_Surface) surf = BRep_Tool::Surface( face );
+ surf->Bounds( u1,u2,v1,v2 );
+ GeomAPI_ProjectPointOnSurf project;
+ project.Init(surf, u1,u2, v1,v2, tolerance );
+ for ( size_t i = 0; i < nb_points; i++)
+ {
+ if ( isInsideRes[ i ]) continue;
+ gp_Pnt aPnt( coords[3*i], coords[3*i+1], coords[3*i+2] );
+ project.Perform( aPnt );
+ if ( project.IsDone() &&
+ project.NbPoints() > 0 &&
+ project.LowerDistance() <= tolerance )
+ {
+ Quantity_Parameter u, v;
+ project.LowerDistanceParameters(u, v);
+ gp_Pnt2d uv( u, v );
+ BRepClass_FaceClassifier FC ( face, uv, tolerance );
+ isInsideRes[ i ] = (( FC.State() == TopAbs_IN ) || ( FC.State() == TopAbs_ON ));
+ nb_points_inside += isInsideRes[ i ];
+ }
+ }
+ break;
+ }
+ case TopAbs_EDGE:
+ {
+ Standard_Real f,l;
+ const TopoDS_Edge& edge = TopoDS::Edge( aShape );
+ Handle(Geom_Curve) curve = BRep_Tool::Curve( edge, f, l );
+ GeomAPI_ProjectPointOnCurve project;
+ project.Init( curve, f, l );
+ for ( size_t i = 0; i < nb_points; i++)
+ {
+ if ( isInsideRes[ i ]) continue;
+ gp_Pnt aPnt( coords[3*i], coords[3*i+1], coords[3*i+2] );
+ project.Perform( aPnt );
+ isInsideRes[ i ] = ( project.NbPoints() > 0 &&
+ project.LowerDistance() <= tolerance );
+ nb_points_inside += isInsideRes[ i ];
+ }
+ break;
+ }
+ case TopAbs_VERTEX:
+ {
+ gp_Pnt aVPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ));
+ for ( size_t i = 0; i < nb_points; i++)
+ {
+ if ( isInsideRes[ i ]) continue;
+ gp_Pnt aPnt( coords[3*i], coords[3*i+1], coords[3*i+2] );
+ isInsideRes[ i ] = ( aPnt.SquareDistance( aVPnt ) <= tolerance * tolerance );
+ nb_points_inside += isInsideRes[ i ];
+ }
+ break;
+ }
+ default:;
+ } // switch ( aShape.ShapeType() )
+ }
+ }
+ }
+ }
+ return isInsideRes;
+}
+
+//=============================================================================
+/*!
+ * 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 {
+ OCC_CATCH_SIGNALS;
+
+ gp_Pnt aPnt1, aPnt2;
+
+ MinDist = GEOMUtils::GetMinDistance(aShape1, aShape2, aPnt1, aPnt2);
+
+ if (MinDist >= 0.0) {
+ aPnt1.Coord(X1, Y1, Z1);
+ aPnt2.Coord(X2, Y2, Z2);
+ } else {
+ return MinDist;
}
}
catch (Standard_Failure) {
return MinDist;
}
+//=======================================================================
+/*!
+ * Get coordinates of closest points of two shapes
+ */
+//=======================================================================
+Standard_Integer GEOMImpl_IMeasureOperations::ClosestPoints (Handle(GEOM_Object) theShape1,
+ Handle(GEOM_Object) theShape2,
+ Handle(TColStd_HSequenceOfReal)& theDoubles)
+{
+ SetErrorCode(KO);
+ Standard_Integer nbSolutions = 0;
+
+ if (theShape1.IsNull() || theShape2.IsNull()) return nbSolutions;
+
+ Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction();
+ Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction();
+ if (aRefShape1.IsNull() || aRefShape2.IsNull()) return nbSolutions;
+
+ TopoDS_Shape aShape1 = aRefShape1->GetValue();
+ TopoDS_Shape aShape2 = aRefShape2->GetValue();
+ if (aShape1.IsNull() || aShape2.IsNull()) {
+ SetErrorCode("One of Objects has NULL Shape");
+ return nbSolutions;
+ }
+
+ // Compute the extremities
+ try {
+ OCC_CATCH_SIGNALS;
+
+ // skl 30.06.2008
+ // additional workaround for bugs 19899, 19908 and 19910 from Mantis
+ gp_Pnt P1, P2;
+ double dist = GEOMUtils::GetMinDistanceSingular(aShape1, aShape2, P1, P2);
+ if (dist > -1.0) {
+ nbSolutions = 1;
+
+ theDoubles->Append(P1.X());
+ theDoubles->Append(P1.Y());
+ theDoubles->Append(P1.Z());
+ theDoubles->Append(P2.X());
+ theDoubles->Append(P2.Y());
+ theDoubles->Append(P2.Z());
+
+ SetErrorCode(OK);
+ return nbSolutions;
+ }
+
+ BRepExtrema_DistShapeShape dst (aShape1, aShape2);
+ if (dst.IsDone()) {
+ nbSolutions = dst.NbSolution();
+ if (theDoubles.IsNull()) theDoubles = new TColStd_HSequenceOfReal;
+
+ gp_Pnt P1, P2;
+ for (int i = 1; i <= nbSolutions; i++) {
+ P1 = dst.PointOnShape1(i);
+ P2 = dst.PointOnShape2(i);
+
+ theDoubles->Append(P1.X());
+ theDoubles->Append(P1.Y());
+ theDoubles->Append(P1.Z());
+ theDoubles->Append(P2.X());
+ theDoubles->Append(P2.Y());
+ theDoubles->Append(P2.Z());
+ }
+ }
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return nbSolutions;
+ }
+
+ SetErrorCode(OK);
+ return nbSolutions;
+}
+
//=======================================================================
/*!
* Get coordinates of point
}
try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
-#endif
gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
theX = aPnt.X();
theY = aPnt.Y();
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;
}
try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
OCC_CATCH_SIGNALS;
-#endif
TopoDS_Edge E1 = TopoDS::Edge(aLine1);
TopoDS_Edge E2 = TopoDS::Edge(aLine2);
Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
Handle(Geom_Curve) C2 = BRep_Tool::Curve(E2,fp,lp);
- if (!C1->IsKind(STANDARD_TYPE(Geom_Line)) ||
+ if ( C1.IsNull() || C2.IsNull() ||
+ !C1->IsKind(STANDARD_TYPE(Geom_Line)) ||
!C2->IsKind(STANDARD_TYPE(Geom_Line)))
{
SetErrorCode("The edges must be linear");
gp_Lin aLin2 = L2->Lin();
anAngle = aLin1.Angle(aLin2);
- anAngle /= PI180; // convert radians into degrees
+ anAngle *= 180. / M_PI; // convert radians into degrees
+
+ if (anAngle > 90.0) {
+ anAngle = 180.0 - anAngle;
+ }
SetErrorCode(OK);
}
}
//=======================================================================
-//function : StructuralDump
-//purpose : Structural (data exchange) style of output.
+/*!
+ * Compute angle (in degrees) between two vectors
+ */
//=======================================================================
-void GEOMImpl_IMeasureOperations::StructuralDump (const BRepCheck_Analyzer& theAna,
- const TopoDS_Shape& theShape,
- TCollection_AsciiString& theDump)
+Standard_Real GEOMImpl_IMeasureOperations::GetAngleBtwVectors (Handle(GEOM_Object) theVec1,
+ Handle(GEOM_Object) theVec2)
{
- Standard_Integer i;
- theDump.Clear();
- theDump += " -- The Shape has problems :\n";
- theDump += " Check Count\n";
- theDump += " ------------------------------------------------\n";
-
- Standard_Integer last_stat = (Standard_Integer)BRepCheck_CheckFail;
- Handle(TColStd_HArray1OfInteger) NbProblems =
- new TColStd_HArray1OfInteger(1, last_stat);
- for (i = 1; i <= last_stat; i++)
- NbProblems->SetValue(i,0);
-
- Handle(TopTools_HSequenceOfShape) sl;
- sl = new TopTools_HSequenceOfShape();
- TopTools_DataMapOfShapeListOfShape theMap;
- theMap.Clear();
- GetProblemShapes(theAna, theShape, sl, NbProblems, theMap);
- theMap.Clear();
-
- Standard_Integer count = 0;
- count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnCurve);
- if (count > 0) {
- theDump += " Invalid Point on Curve ................... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnCurveOnSurface);
- if (count > 0) {
- theDump += " Invalid Point on CurveOnSurface .......... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnSurface);
- if (count > 0) {
- theDump += " Invalid Point on Surface ................. ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_No3DCurve);
- if (count > 0) {
- theDump += " No 3D Curve .............................. ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_Multiple3DCurve);
- if (count > 0) {
- theDump += " Multiple 3D Curve ........................ ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_Invalid3DCurve);
- if (count > 0) {
- theDump += " Invalid 3D Curve ......................... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_NoCurveOnSurface);
- if (count > 0) {
- theDump += " No Curve on Surface ...................... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidCurveOnSurface);
- if (count > 0) {
- theDump += " Invalid Curve on Surface ................. ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidCurveOnClosedSurface);
- if (count > 0) {
- theDump += " Invalid Curve on closed Surface .......... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidSameRangeFlag);
- if (count > 0) {
- theDump += " Invalid SameRange Flag ................... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidSameParameterFlag);
- if (count > 0) {
- theDump += " Invalid SameParameter Flag ............... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidDegeneratedFlag);
- if (count > 0) {
- theDump += " Invalid Degenerated Flag ................. ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_FreeEdge);
- if (count > 0) {
- theDump += " Free Edge ................................ ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidMultiConnexity);
- if (count > 0) {
- theDump += " Invalid MultiConnexity ................... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidRange);
- if (count > 0) {
- theDump += " Invalid Range ............................ ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_EmptyWire);
- if (count > 0) {
- theDump += " Empty Wire ............................... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantEdge);
- if (count > 0) {
- theDump += " Redundant Edge ........................... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_SelfIntersectingWire);
- if (count > 0) {
- theDump += " Self Intersecting Wire ................... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_NoSurface);
- if (count > 0) {
- theDump += " No Surface ............................... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidWire);
- if (count > 0) {
- theDump += " Invalid Wire ............................. ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantWire);
- if (count > 0) {
- theDump += " Redundant Wire ........................... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_IntersectingWires);
- if (count > 0) {
- theDump += " Intersecting Wires ....................... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidImbricationOfWires);
- if (count > 0) {
- theDump += " Invalid Imbrication of Wires ............. ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_EmptyShell);
- if (count > 0) {
- theDump += " Empty Shell .............................. ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantFace);
- if (count > 0) {
- theDump += " Redundant Face ........................... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_UnorientableShape);
- if (count > 0) {
- theDump += " Unorientable Shape ....................... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_NotClosed);
- if (count > 0) {
- theDump += " Not Closed ............................... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_NotConnected);
- if (count > 0) {
- theDump += " Not Connected ............................ ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_SubshapeNotInShape);
- if (count > 0) {
- theDump += " Subshape not in Shape .................... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_BadOrientation);
- if (count > 0) {
- theDump += " Bad Orientation .......................... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_BadOrientationOfSubshape);
- if (count > 0) {
- theDump += " Bad Orientation of Subshape .............. ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
- count = NbProblems->Value((Standard_Integer)BRepCheck_CheckFail);
- if (count > 0) {
- theDump += " checkshape failure ....................... ";
- theDump += TCollection_AsciiString(count) + "\n";
- }
-
- theDump += " ------------------------------------------------\n";
- theDump += "*** Shapes with problems : ";
- theDump += TCollection_AsciiString(sl->Length()) + "\n";
-
- Standard_Integer nbv, nbe, nbw, nbf, nbs, nbo;
- nbv = nbe = nbw = nbf = nbs = nbo = 0;
-
- for (i = 1; i <= sl->Length(); i++) {
- TopoDS_Shape shi = sl->Value(i);
- TopAbs_ShapeEnum sti = shi.ShapeType();
- switch (sti) {
- case TopAbs_VERTEX : nbv++; break;
- case TopAbs_EDGE : nbe++; break;
- case TopAbs_WIRE : nbw++; break;
- case TopAbs_FACE : nbf++; break;
- case TopAbs_SHELL : nbs++; break;
- case TopAbs_SOLID : nbo++; break;
- default : break;
+ SetErrorCode(KO);
+
+ Standard_Real anAngle = -1.0;
+
+ if (theVec1.IsNull() || theVec2.IsNull())
+ return anAngle;
+
+ if (theVec1->GetType() != GEOM_VECTOR || theVec2->GetType() != GEOM_VECTOR) {
+ SetErrorCode("Two vectors must be given");
+ 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;
+ }
+
+ try {
+ OCC_CATCH_SIGNALS;
+ TopoDS_Edge aE1 = TopoDS::Edge(aVec1);
+ TopoDS_Edge aE2 = TopoDS::Edge(aVec2);
+
+ TopoDS_Vertex aP11, aP12, aP21, aP22;
+ TopExp::Vertices(aE1, aP11, aP12, Standard_True);
+ TopExp::Vertices(aE2, aP21, aP22, Standard_True);
+ if (aP11.IsNull() || aP12.IsNull() || aP21.IsNull() || aP22.IsNull()) {
+ SetErrorCode("Bad edge given");
+ return anAngle;
}
+
+ gp_Vec aV1 (BRep_Tool::Pnt(aP11), BRep_Tool::Pnt(aP12));
+ gp_Vec aV2 (BRep_Tool::Pnt(aP21), BRep_Tool::Pnt(aP22)) ;
+
+ anAngle = aV1.Angle(aV2);
+ anAngle *= 180. / M_PI; // convert radians into degrees
+
+ SetErrorCode(OK);
+ }
+ catch (Standard_Failure)
+ {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
}
- if (nbv > 0) {
- theDump += "VERTEX : ";
- if (nbv < 10) theDump += " ";
- theDump += TCollection_AsciiString(nbv) + "\n";
+ return anAngle;
+}
+
+
+//=============================================================================
+/*!
+ * CurveCurvatureByParam
+ */
+//=============================================================================
+Standard_Real GEOMImpl_IMeasureOperations::CurveCurvatureByParam
+ (Handle(GEOM_Object) theCurve, Standard_Real& theParam)
+{
+ SetErrorCode(KO);
+ Standard_Real aRes = -1.0;
+
+ if(theCurve.IsNull()) return aRes;
+
+ Handle(GEOM_Function) aRefShape = theCurve->GetLastFunction();
+ if(aRefShape.IsNull()) return aRes;
+
+ TopoDS_Shape aShape = aRefShape->GetValue();
+ if(aShape.IsNull()) {
+ SetErrorCode("One of Objects has NULL Shape");
+ return aRes;
}
- if (nbe > 0) {
- theDump += "EDGE : ";
- if (nbe < 10) theDump += " ";
- theDump += TCollection_AsciiString(nbe) + "\n";
+
+ Standard_Real aFP, aLP, aP;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aShape), aFP, aLP);
+ aP = aFP + (aLP - aFP) * theParam;
+
+ if(aCurve.IsNull()) return aRes;
+
+ //Compute curvature
+ try {
+ OCC_CATCH_SIGNALS;
+ GeomLProp_CLProps Prop = GeomLProp_CLProps
+ (aCurve, aP, 2, Precision::Confusion());
+ aRes = fabs(Prop.Curvature());
+ SetErrorCode(OK);
}
- if (nbw > 0) {
- theDump += "WIRE : ";
- if (nbw < 10) theDump += " ";
- theDump += TCollection_AsciiString(nbw) + "\n";
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return aRes;
}
- if (nbf > 0) {
- theDump += "FACE : ";
- if (nbf < 10) theDump += " ";
- theDump += TCollection_AsciiString(nbf) + "\n";
+
+ if( aRes > Precision::Confusion() )
+ aRes = 1/aRes;
+ else
+ aRes = RealLast();
+
+ return aRes;
+}
+
+
+//=============================================================================
+/*!
+ * CurveCurvatureByPoint
+ */
+//=============================================================================
+Standard_Real GEOMImpl_IMeasureOperations::CurveCurvatureByPoint
+ (Handle(GEOM_Object) theCurve, Handle(GEOM_Object) thePoint)
+{
+ SetErrorCode(KO);
+ Standard_Real aRes = -1.0;
+
+ if( theCurve.IsNull() || thePoint.IsNull() ) return aRes;
+
+ Handle(GEOM_Function) aRefCurve = theCurve->GetLastFunction();
+ Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction();
+ if( aRefCurve.IsNull() || aRefPoint.IsNull() ) return aRes;
+
+ TopoDS_Edge anEdge = TopoDS::Edge(aRefCurve->GetValue());
+ TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue());
+ if( anEdge.IsNull() || aPnt.IsNull() ) {
+ SetErrorCode("One of Objects has NULL Shape");
+ return aRes;
}
- if (nbs > 0) {
- theDump += "SHELL : ";
- if (nbs < 10) theDump += " ";
- theDump += TCollection_AsciiString(nbs) + "\n";
+
+ Standard_Real aFP, aLP;
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFP, aLP);
+ if(aCurve.IsNull()) return aRes;
+ gp_Pnt aPoint = BRep_Tool::Pnt(aPnt);
+
+ //Compute curvature
+ try {
+ OCC_CATCH_SIGNALS;
+ GeomAPI_ProjectPointOnCurve PPCurve(aPoint, aCurve, aFP, aLP);
+ if(PPCurve.NbPoints()>0) {
+ GeomLProp_CLProps Prop = GeomLProp_CLProps
+ (aCurve, PPCurve.LowerDistanceParameter(), 2, Precision::Confusion());
+ aRes = fabs(Prop.Curvature());
+ SetErrorCode(OK);
+ }
}
- if (nbo > 0) {
- theDump += "SOLID : ";
- if (nbo < 10) theDump += " ";
- theDump += TCollection_AsciiString(nbo) + "\n";
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return aRes;
}
+
+ if( aRes > Precision::Confusion() )
+ aRes = 1/aRes;
+ else
+ aRes = RealLast();
+
+ return aRes;
}
-//=======================================================================
-//function : GetProblemShapes
-// purpose : for StructuralDump
-//=======================================================================
-void GEOMImpl_IMeasureOperations::GetProblemShapes (const BRepCheck_Analyzer& theAna,
- const TopoDS_Shape& theShape,
- Handle(TopTools_HSequenceOfShape)& sl,
- Handle(TColStd_HArray1OfInteger)& NbProblems,
- TopTools_DataMapOfShapeListOfShape& theMap)
+
+//=============================================================================
+/*!
+ * getSurfaceCurvatures
+ */
+//=============================================================================
+Standard_Real GEOMImpl_IMeasureOperations::getSurfaceCurvatures
+ (const Handle(Geom_Surface)& aSurf,
+ Standard_Real theUParam,
+ Standard_Real theVParam,
+ Standard_Boolean theNeedMaxCurv)
{
- for (TopoDS_Iterator iter(theShape); iter.More(); iter.Next()) {
- GetProblemShapes(theAna, iter.Value(), sl, NbProblems, theMap);
- }
- TopAbs_ShapeEnum styp = theShape.ShapeType();
- BRepCheck_ListIteratorOfListOfStatus itl;
- TopTools_ListOfShape empty;
- if (!theMap.IsBound(theShape)) {
- theMap.Bind(theShape,empty);
-
- if (!theAna.Result(theShape).IsNull()) {
- itl.Initialize(theAna.Result(theShape)->Status());
- // !!! May be, we have to print all the problems, not only the first one ?
- if (itl.Value() != BRepCheck_NoError) {
- sl->Append(theShape);
- BRepCheck_Status stat = itl.Value();
- NbProblems->SetValue((Standard_Integer)stat,
- NbProblems->Value((Standard_Integer)stat) + 1);
+ SetErrorCode(KO);
+ Standard_Real aRes = 1.0;
+
+ if (aSurf.IsNull()) return aRes;
+
+ try {
+ OCC_CATCH_SIGNALS;
+ GeomLProp_SLProps Prop = GeomLProp_SLProps
+ (aSurf, theUParam, theVParam, 2, Precision::Confusion());
+ if(Prop.IsCurvatureDefined()) {
+ if(Prop.IsUmbilic()) {
+ //cout<<"is umbilic"<<endl;
+ aRes = fabs(Prop.MeanCurvature());
}
+ else {
+ //cout<<"is not umbilic"<<endl;
+ double c1 = fabs(Prop.MaxCurvature());
+ double c2 = fabs(Prop.MinCurvature());
+ if(theNeedMaxCurv)
+ aRes = Max(c1,c2);
+ else
+ aRes = Min(c1,c2);
+ }
+ SetErrorCode(OK);
}
}
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return aRes;
+ }
- switch (styp) {
- case TopAbs_EDGE:
- GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_VERTEX, theMap);
- break;
- case TopAbs_FACE:
- GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_WIRE, theMap);
- GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_EDGE, theMap);
- GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_VERTEX, theMap);
- break;
- case TopAbs_SHELL:
- break;
- case TopAbs_SOLID:
- GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_SHELL, theMap);
- break;
- default:
- break;
+ if( fabs(aRes) > Precision::Confusion() )
+ aRes = 1/aRes;
+ else
+ aRes = RealLast();
+
+ return aRes;
+}
+
+
+//=============================================================================
+/*!
+ * MaxSurfaceCurvatureByParam
+ */
+//=============================================================================
+Standard_Real GEOMImpl_IMeasureOperations::MaxSurfaceCurvatureByParam
+ (Handle(GEOM_Object) theSurf,
+ Standard_Real& theUParam,
+ Standard_Real& theVParam)
+{
+ SetErrorCode(KO);
+ Standard_Real aRes = -1.0;
+
+ if (theSurf.IsNull()) return aRes;
+
+ Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
+ if(aRefShape.IsNull()) return aRes;
+
+ TopoDS_Shape aShape = aRefShape->GetValue();
+ if(aShape.IsNull()) {
+ SetErrorCode("One of Objects has NULL Shape");
+ return aRes;
}
+
+ TopoDS_Face F = TopoDS::Face(aShape);
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
+
+ //Compute the parameters
+ Standard_Real U1,U2,V1,V2;
+ ShapeAnalysis::GetFaceUVBounds(F,U1,U2,V1,V2);
+ Standard_Real U = U1 + (U2-U1)*theUParam;
+ Standard_Real V = V1 + (V2-V1)*theVParam;
+
+ return getSurfaceCurvatures(aSurf, U, V, true);
+}
+
+
+//=============================================================================
+/*!
+ * MaxSurfaceCurvatureByPoint
+ */
+//=============================================================================
+Standard_Real GEOMImpl_IMeasureOperations::MaxSurfaceCurvatureByPoint
+ (Handle(GEOM_Object) theSurf, Handle(GEOM_Object) thePoint)
+{
+ SetErrorCode(KO);
+ Standard_Real aRes = -1.0;
+
+ if( theSurf.IsNull() || thePoint.IsNull() ) return aRes;
+
+ Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
+ Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction();
+ if( aRefShape.IsNull() || aRefPoint.IsNull() ) return aRes;
+
+ TopoDS_Face aFace = TopoDS::Face(aRefShape->GetValue());
+ TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue());
+ if( aFace.IsNull() || aPnt.IsNull() ) {
+ SetErrorCode("One of Objects has NULL Shape");
+ return 0;
+ }
+
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
+ if(aSurf.IsNull()) return aRes;
+ gp_Pnt aPoint = BRep_Tool::Pnt(aPnt);
+
+ //Compute the parameters
+ ShapeAnalysis_Surface sas(aSurf);
+ gp_Pnt2d UV = sas.ValueOfUV(aPoint,Precision::Confusion());
+
+ return getSurfaceCurvatures(aSurf, UV.X(), UV.Y(), true);
+}
+
+
+//=============================================================================
+/*!
+ * MinSurfaceCurvatureByParam
+ */
+//=============================================================================
+Standard_Real GEOMImpl_IMeasureOperations::MinSurfaceCurvatureByParam
+ (Handle(GEOM_Object) theSurf,
+ Standard_Real& theUParam,
+ Standard_Real& theVParam)
+{
+ SetErrorCode(KO);
+ Standard_Real aRes = -1.0;
+
+ if (theSurf.IsNull()) return aRes;
+
+ Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
+ if(aRefShape.IsNull()) return aRes;
+
+ TopoDS_Shape aShape = aRefShape->GetValue();
+ if(aShape.IsNull()) {
+ SetErrorCode("One of Objects has NULL Shape");
+ return aRes;
+ }
+
+ TopoDS_Face F = TopoDS::Face(aShape);
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
+
+ //Compute the parameters
+ Standard_Real U1,U2,V1,V2;
+ ShapeAnalysis::GetFaceUVBounds(F,U1,U2,V1,V2);
+ Standard_Real U = U1 + (U2-U1)*theUParam;
+ Standard_Real V = V1 + (V2-V1)*theVParam;
+
+ return getSurfaceCurvatures(aSurf, U, V, false);
+}
+
+
+//=============================================================================
+/*!
+ * MinSurfaceCurvatureByPoint
+ */
+//=============================================================================
+Standard_Real GEOMImpl_IMeasureOperations::MinSurfaceCurvatureByPoint
+ (Handle(GEOM_Object) theSurf, Handle(GEOM_Object) thePoint)
+{
+ SetErrorCode(KO);
+ Standard_Real aRes = -1.0;
+
+ if( theSurf.IsNull() || thePoint.IsNull() ) return aRes;
+
+ Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
+ Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction();
+ if( aRefShape.IsNull() || aRefPoint.IsNull() ) return aRes;
+
+ TopoDS_Face aFace = TopoDS::Face(aRefShape->GetValue());
+ TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue());
+ if( aFace.IsNull() || aPnt.IsNull() ) {
+ SetErrorCode("One of Objects has NULL Shape");
+ return 0;
+ }
+
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
+ if(aSurf.IsNull()) return aRes;
+ gp_Pnt aPoint = BRep_Tool::Pnt(aPnt);
+
+ //Compute the parameters
+ ShapeAnalysis_Surface sas(aSurf);
+ gp_Pnt2d UV = sas.ValueOfUV(aPoint,Precision::Confusion());
+
+ return getSurfaceCurvatures(aSurf, UV.X(), UV.Y(), false);
}
//=======================================================================
-//function : Contains
+//function : FillErrorsSub
+//purpose : Fill the errors list of subshapes on shape.
//=======================================================================
-static Standard_Boolean Contains (const TopTools_ListOfShape& L,
- const TopoDS_Shape& S)
+void GEOMImpl_IMeasureOperations::FillErrorsSub
+ (const BRepCheck_Analyzer &theAna,
+ const TopoDS_Shape &theShape,
+ const TopAbs_ShapeEnum theSubType,
+ TopTools_DataMapOfIntegerListOfShape &theMapErrors) const
{
- TopTools_ListIteratorOfListOfShape it;
- for (it.Initialize(L); it.More(); it.Next()) {
- if (it.Value().IsSame(S)) {
- return Standard_True;
+ TopExp_Explorer anExp(theShape, theSubType);
+ TopTools_MapOfShape aMapSubShapes;
+
+ for (; anExp.More(); anExp.Next()) {
+ const TopoDS_Shape &aSubShape = anExp.Current();
+
+ if (aMapSubShapes.Add(aSubShape)) {
+ const Handle(BRepCheck_Result) &aRes = theAna.Result(aSubShape);
+
+ for (aRes->InitContextIterator();
+ aRes->MoreShapeInContext();
+ aRes->NextShapeInContext()) {
+ if (aRes->ContextualShape().IsSame(theShape)) {
+ BRepCheck_ListIteratorOfListOfStatus itl(aRes->StatusOnShape());
+
+ if (itl.Value() != BRepCheck_NoError) {
+ // Add all errors for theShape and its sub-shape.
+ for (;itl.More(); itl.Next()) {
+ const Standard_Integer aStat = (Standard_Integer)itl.Value();
+
+ if (!theMapErrors.IsBound(aStat)) {
+ TopTools_ListOfShape anEmpty;
+
+ theMapErrors.Bind(aStat, anEmpty);
+ }
+
+ TopTools_ListOfShape &theShapes = theMapErrors.ChangeFind(aStat);
+
+ theShapes.Append(aSubShape);
+ theShapes.Append(theShape);
+ }
+ }
+ }
+
+ break;
+ }
}
}
- return Standard_False;
}
//=======================================================================
-//function : GetProblemSub
-// purpose : for StructuralDump
+//function : FillErrors
+//purpose : Fill the errors list.
//=======================================================================
-void GEOMImpl_IMeasureOperations::GetProblemSub (const BRepCheck_Analyzer& theAna,
- const TopoDS_Shape& theShape,
- Handle(TopTools_HSequenceOfShape)& sl,
- Handle(TColStd_HArray1OfInteger)& NbProblems,
- const TopAbs_ShapeEnum Subtype,
- TopTools_DataMapOfShapeListOfShape& theMap)
+void GEOMImpl_IMeasureOperations::FillErrors
+ (const BRepCheck_Analyzer &theAna,
+ const TopoDS_Shape &theShape,
+ TopTools_DataMapOfIntegerListOfShape &theMapErrors,
+ TopTools_MapOfShape &theMapShapes) const
{
- BRepCheck_ListIteratorOfListOfStatus itl;
- TopExp_Explorer exp;
- for (exp.Init(theShape, Subtype); exp.More(); exp.Next()) {
- const TopoDS_Shape& sub = exp.Current();
-
- const Handle(BRepCheck_Result)& res = theAna.Result(sub);
- for (res->InitContextIterator();
- res->MoreShapeInContext();
- res->NextShapeInContext()) {
- if (res->ContextualShape().IsSame(theShape) && !Contains(theMap(sub), theShape)) {
- theMap(sub).Append(theShape);
- itl.Initialize(res->StatusOnShape());
-
- if (itl.Value() != BRepCheck_NoError) {
- Standard_Integer ii = 0;
-
- for (ii = 1; ii <= sl->Length(); ii++)
- if (sl->Value(ii).IsSame(sub)) break;
-
- if (ii > sl->Length()) {
- sl->Append(sub);
- BRepCheck_Status stat = itl.Value();
- NbProblems->SetValue((Standard_Integer)stat,
- NbProblems->Value((Standard_Integer)stat) + 1);
- }
- for (ii = 1; ii <= sl->Length(); ii++)
- if (sl->Value(ii).IsSame(theShape)) break;
- if (ii > sl->Length()) {
- sl->Append(theShape);
- BRepCheck_Status stat = itl.Value();
- NbProblems->SetValue((Standard_Integer)stat,
- NbProblems->Value((Standard_Integer)stat) + 1);
+ if (theMapShapes.Add(theShape)) {
+ // Fill errors of child shapes.
+ for (TopoDS_Iterator iter(theShape); iter.More(); iter.Next()) {
+ FillErrors(theAna, iter.Value(), theMapErrors, theMapShapes);
+ }
+
+ // Fill errors of theShape.
+ const Handle(BRepCheck_Result) &aRes = theAna.Result(theShape);
+
+ if (!aRes.IsNull()) {
+ BRepCheck_ListIteratorOfListOfStatus itl(aRes->Status());
+
+ if (itl.Value() != BRepCheck_NoError) {
+ // Add all errors for theShape.
+ for (;itl.More(); itl.Next()) {
+ const Standard_Integer aStat = (Standard_Integer)itl.Value();
+
+ if (!theMapErrors.IsBound(aStat)) {
+ TopTools_ListOfShape anEmpty;
+
+ theMapErrors.Bind(aStat, anEmpty);
}
- }
- break;
+
+ theMapErrors.ChangeFind(aStat).Append(theShape);
+ }
+ }
+ }
+
+ // Add errors of subshapes on theShape.
+ const TopAbs_ShapeEnum aType = theShape.ShapeType();
+
+ switch (aType) {
+ case TopAbs_EDGE:
+ FillErrorsSub(theAna, theShape, TopAbs_VERTEX, theMapErrors);
+ break;
+ case TopAbs_FACE:
+ FillErrorsSub(theAna, theShape, TopAbs_WIRE, theMapErrors);
+ FillErrorsSub(theAna, theShape, TopAbs_EDGE, theMapErrors);
+ FillErrorsSub(theAna, theShape, TopAbs_VERTEX, theMapErrors);
+ break;
+ case TopAbs_SOLID:
+ FillErrorsSub(theAna, theShape, TopAbs_SHELL, theMapErrors);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+//=======================================================================
+//function : FillErrors
+//purpose : Fill the errors list.
+//=======================================================================
+void GEOMImpl_IMeasureOperations::FillErrors
+ (const BRepCheck_Analyzer &theAna,
+ const TopoDS_Shape &theShape,
+ std::list<ShapeError> &theErrors) const
+{
+ // Fill the errors map.
+ TopTools_DataMapOfIntegerListOfShape aMapErrors;
+ TopTools_MapOfShape aMapShapes;
+
+ FillErrors(theAna, theShape, aMapErrors, aMapShapes);
+
+ // Map sub-shapes and their indices
+ TopTools_IndexedMapOfShape anIndices;
+
+ TopExp::MapShapes(theShape, anIndices);
+
+ TopTools_DataMapIteratorOfDataMapOfIntegerListOfShape aMapIter(aMapErrors);
+
+ for (; aMapIter.More(); aMapIter.Next()) {
+ ShapeError anError;
+
+ anError.error = (BRepCheck_Status)aMapIter.Key();
+
+ TopTools_ListIteratorOfListOfShape aListIter(aMapIter.Value());
+ TopTools_MapOfShape aMapUnique;
+
+ for (; aListIter.More(); aListIter.Next()) {
+ const TopoDS_Shape &aShape = aListIter.Value();
+
+ if (aMapUnique.Add(aShape)) {
+ const Standard_Integer anIndex = anIndices.FindIndex(aShape);
+
+ anError.incriminated.push_back(anIndex);
}
}
+
+ if (!anError.incriminated.empty()) {
+ theErrors.push_back(anError);
+ }
}
}