+ //Compute the sub-shape value
+ Standard_Boolean isWarning = Standard_False;
+ try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+ OCC_CATCH_SIGNALS;
+#endif
+ if (!GetSolver()->ComputeFunction(aFunction)) {
+ SetErrorCode("Shape driver failed to glue faces");
+ return NULL;
+ }
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ // to provide warning
+ if (!aFunction->GetValue().IsNull()) {
+ isWarning = Standard_True;
+ } else {
+ return NULL;
+ }
+ }
+
+ //Make a Python command
+
+ GEOM::TPythonDump pd(aFunction);
+ pd << aGlued << " = geompy.MakeGlueFacesByList("
+ << theShape << ", " << theTolerance << ", [";
+ // Faces
+ it = theFaces.begin();
+ if (it != theFaces.end()) {
+ pd << (*it++);
+ while (it != theFaces.end()) {
+ pd << ", " << (*it++);
+ }
+ }
+ pd << "])";
+
+ // to provide warning
+ if (!isWarning) SetErrorCode(OK);
+ return aGlued;
+}
+
+//=============================================================================
+/*!
+ * GetExistingSubObjects
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetExistingSubObjects
+ (Handle(GEOM_Object) theShape,
+ const Standard_Boolean theGroupsOnly)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull()) return NULL;
+
+ Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
+ if (aMainShape.IsNull()) return NULL;
+
+ Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+ SetErrorCode(NOT_FOUND_ANY);
+
+ if (!aMainShape->HasSubShapeReferences()) return aSeq;
+ const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
+ if (aListEntries.IsEmpty()) return aSeq;
+
+ SetErrorCode(KO);
+
+ TCollection_AsciiString anAsciiList;
+
+ TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
+ for (; anIt.More(); anIt.Next()) {
+ TCollection_ExtendedString anEntry = anIt.Value();
+ Standard_Integer aStrLen = anEntry.LengthOfCString();
+ char* anEntryStr = new char[aStrLen];
+ anEntry.ToUTF8CString(anEntryStr);
+ Handle(GEOM_Object) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
+ if (!anObj.IsNull()) {
+ if (!theGroupsOnly || anObj->GetType() == GEOM_GROUP) {
+ aSeq->Append(anObj);
+
+ // for python command
+ anAsciiList += anEntryStr;
+ anAsciiList += ",";
+ }
+ }
+ delete [] anEntryStr;
+ }
+
+ if (aSeq->Length() == 0) {
+ SetErrorCode(NOT_FOUND_ANY);
+ return aSeq;
+ }
+
+ //Make a Python command
+ anAsciiList.Trunc(anAsciiList.Length() - 1);
+
+ GEOM::TPythonDump pd (aMainShape, /*append=*/true);
+ pd << "[" << anAsciiList.ToCString();
+ pd << "] = geompy.GetExistingSubObjects(";
+ pd << theShape << ", " << (int)theGroupsOnly << ")";
+
+ SetErrorCode(OK);
+
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ * MakeExplode
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
+ (Handle(GEOM_Object) theShape,
+ const Standard_Integer theShapeType,
+ const Standard_Boolean isSorted)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull()) return NULL;
+ TopoDS_Shape aShape = theShape->GetValue();
+ if (aShape.IsNull()) return NULL;
+
+ Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
+
+ Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+ Handle(GEOM_Object) anObj;
+ TopTools_MapOfShape mapShape;
+ TopTools_ListOfShape listShape;
+
+ if (aShape.ShapeType() == TopAbs_COMPOUND &&
+ (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
+ TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
+ TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
+ TopoDS_Iterator It (aShape, Standard_True, Standard_True);
+ for (; It.More(); It.Next()) {
+ if (mapShape.Add(It.Value())) {
+ if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
+ TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
+ listShape.Append(It.Value());
+ }
+ }
+ }
+ } else {
+ TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
+ for (; exp.More(); exp.Next())
+ if (mapShape.Add(exp.Current()))
+ listShape.Append(exp.Current());
+ }
+
+ if (listShape.IsEmpty()) {
+ //SetErrorCode("The given shape has no sub-shapes of the requested type");
+ SetErrorCode(NOT_FOUND_ANY); // NPAL18017
+ return aSeq;
+ }
+
+ if (isSorted)
+ SortShapes(listShape);
+
+ TopTools_IndexedMapOfShape anIndices;
+ TopExp::MapShapes(aShape, anIndices);
+ Handle(TColStd_HArray1OfInteger) anArray;
+
+ TopTools_ListIteratorOfListOfShape itSub (listShape);
+ TCollection_AsciiString anAsciiList, anEntry;
+ for (int index = 1; itSub.More(); itSub.Next(), ++index)
+ {
+ TopoDS_Shape aValue = itSub.Value();
+ anArray = new TColStd_HArray1OfInteger(1,1);
+ anArray->SetValue(1, anIndices.FindIndex(aValue));
+
+ //anObj = GetEngine()->AddSubShape(theShape, anArray);
+ {
+ anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
+ Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
+ if (aFunction.IsNull()) return aSeq;
+
+ GEOM_ISubShape aSSI (aFunction);
+ aSSI.SetMainShape(aMainShape);
+ aSSI.SetIndices(anArray);
+
+ // Set function value directly, as we know it.
+ // Usage of Solver here would lead to significant loss of time,
+ // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
+ // on the main shape for each being calculated sub-shape separately.
+ aFunction->SetValue(aValue);
+ }
+
+ if (!anObj.IsNull()) {
+ aSeq->Append(anObj);
+
+ // for python command
+ TDF_Tool::Entry(anObj->GetEntry(), anEntry);
+ anAsciiList += anEntry;
+ anAsciiList += ",";
+ }
+ }
+
+ //Make a Python command
+ anAsciiList.Trunc(anAsciiList.Length() - 1);
+
+ GEOM::TPythonDump pd (aMainShape, /*append=*/true);
+ pd << "[" << anAsciiList.ToCString();
+ pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
+ pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
+
+ SetErrorCode(OK);
+
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ * SubShapeAllIDs
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
+ (Handle(GEOM_Object) theShape,
+ const Standard_Integer theShapeType,
+ const Standard_Boolean isSorted)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull()) return NULL;
+ TopoDS_Shape aShape = theShape->GetValue();
+ if (aShape.IsNull()) return NULL;
+
+ Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
+ TopTools_MapOfShape mapShape;
+ TopTools_ListOfShape listShape;
+
+ if (aShape.ShapeType() == TopAbs_COMPOUND &&
+ (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
+ TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
+ TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
+ TopoDS_Iterator It (aShape, Standard_True, Standard_True);
+ for (; It.More(); It.Next()) {
+ if (mapShape.Add(It.Value())) {
+ if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
+ TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
+ listShape.Append(It.Value());
+ }
+ }
+ }
+ } else {
+ TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
+ for (; exp.More(); exp.Next())
+ if (mapShape.Add(exp.Current()))
+ listShape.Append(exp.Current());
+ }
+
+ if (listShape.IsEmpty()) {
+ //SetErrorCode("The given shape has no sub-shapes of the requested type");
+ SetErrorCode(NOT_FOUND_ANY); // NPAL18017
+ return aSeq;
+ }
+
+ if (isSorted)
+ SortShapes(listShape);
+
+ TopTools_IndexedMapOfShape anIndices;
+ TopExp::MapShapes(aShape, anIndices);
+ Handle(TColStd_HArray1OfInteger) anArray;
+
+ TopTools_ListIteratorOfListOfShape itSub (listShape);
+ for (int index = 1; itSub.More(); itSub.Next(), ++index) {
+ TopoDS_Shape aValue = itSub.Value();
+ aSeq->Append(anIndices.FindIndex(aValue));
+ }
+
+ Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
+
+ //Make a Python command
+ GEOM::TPythonDump pd (aFunction, /*append=*/true);
+ pd << "listSubShapeIDs = geompy.SubShapeAll";
+ pd << (isSorted ? "SortedIDs(" : "IDs(");
+ pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ * GetSubShape
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
+ (Handle(GEOM_Object) theMainShape,
+ const Standard_Integer theID)
+{
+ SetErrorCode(KO);
+
+ if (theMainShape.IsNull()) return NULL;
+
+ Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
+ anArray->SetValue(1, theID);
+ Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
+ if (anObj.IsNull()) {
+ SetErrorCode("Can not get a sub-shape with the given ID");
+ return NULL;
+ }
+
+ Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+ //Make a Python command
+ GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
+ << theMainShape << ", [" << theID << "])";
+
+ SetErrorCode(OK);
+ return anObj;
+}
+
+//=============================================================================
+/*!
+ * GetSubShapeIndex
+ */
+//=============================================================================
+Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
+ Handle(GEOM_Object) theSubShape)
+{
+ SetErrorCode(KO);
+
+ TopoDS_Shape aMainShape = theMainShape->GetValue();
+ TopoDS_Shape aSubShape = theSubShape->GetValue();
+
+ if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
+
+ TopTools_IndexedMapOfShape anIndices;
+ TopExp::MapShapes(aMainShape, anIndices);
+ if (anIndices.Contains(aSubShape)) {
+ SetErrorCode(OK);
+ return anIndices.FindIndex(aSubShape);
+ }
+
+ return -1;
+}
+
+//=============================================================================
+/*!
+ * GetTopologyIndex
+ */
+//=============================================================================
+Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
+ Handle(GEOM_Object) theSubShape)
+{
+ SetErrorCode(OK);
+
+ TopoDS_Shape aMainShape = theMainShape->GetValue();
+ TopoDS_Shape aSubShape = theSubShape->GetValue();
+
+ if (aMainShape.IsNull() || aSubShape.IsNull()) {
+ SetErrorCode("Null argument shape given");
+ return -1;
+ }
+
+ int index = 1;
+ if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
+ TopoDS_Iterator it;
+ TopTools_ListOfShape CL;
+ CL.Append(aMainShape);
+ TopTools_ListIteratorOfListOfShape itC;
+ for (itC.Initialize(CL); itC.More(); itC.Next()) {
+ for (it.Initialize(itC.Value()); it.More(); it.Next()) {
+ if (it.Value().ShapeType() == TopAbs_COMPOUND) {
+ if (it.Value().IsSame(aSubShape))
+ return index;
+ else
+ index++;
+ CL.Append(it.Value());
+ }
+ }
+ }
+ } else {
+ TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
+ TopTools_MapOfShape M;
+ for (; anExp.More(); anExp.Next()) {
+ if (M.Add(anExp.Current())) {
+ if (anExp.Current().IsSame(aSubShape))
+ return index;
+ index++;
+ }
+ }
+ }
+
+ SetErrorCode("The sub-shape does not belong to the main shape");
+ return -1;
+}
+
+//=============================================================================
+/*!
+ * GetShapeTypeString
+ */
+//=============================================================================
+TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
+{
+ SetErrorCode(KO);
+
+ TCollection_AsciiString aTypeName ("Null Shape");
+
+ TopoDS_Shape aShape = theShape->GetValue();
+ if (aShape.IsNull())
+ return aTypeName;
+
+ switch (aShape.ShapeType() )
+ {
+ case TopAbs_COMPOUND:
+ aTypeName = "Compound";
+ break;
+ case TopAbs_COMPSOLID:
+ aTypeName = "Compound Solid";
+ break;
+ case TopAbs_SOLID:
+ aTypeName = "Solid";
+ break;
+ case TopAbs_SHELL:
+ aTypeName = "Shell";
+ break;
+ case TopAbs_FACE:
+ {
+ BRepAdaptor_Surface surf (TopoDS::Face(aShape));
+ if (surf.GetType() == GeomAbs_Plane)
+ aTypeName = "Plane";
+ else if (surf.GetType() == GeomAbs_Cylinder)
+ aTypeName = "Cylindrical Face";
+ else if (surf.GetType() == GeomAbs_Sphere)
+ aTypeName = "Spherical Face";
+ else if (surf.GetType() == GeomAbs_Torus)
+ aTypeName = "Toroidal Face";
+ else if (surf.GetType() == GeomAbs_Cone)
+ aTypeName = "Conical Face";
+ else
+ aTypeName = "GEOM::FACE";
+ }
+ break;
+ case TopAbs_WIRE:
+ aTypeName = "Wire";
+ break;
+ case TopAbs_EDGE:
+ {
+ BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
+ if (curv.GetType() == GeomAbs_Line) {
+ if ((Abs(curv.FirstParameter()) >= 1E6) ||
+ (Abs(curv.LastParameter()) >= 1E6))
+ aTypeName = "Line";
+ else
+ aTypeName = "Edge";
+ } else if (curv.GetType() == GeomAbs_Circle) {
+ if (curv.IsClosed())
+ aTypeName = "Circle";
+ else
+ aTypeName = "Arc";
+ } else {
+ aTypeName = "Edge";
+ }
+ }
+ break;
+ case TopAbs_VERTEX:
+ aTypeName = "Vertex";
+ break;
+ case TopAbs_SHAPE:
+ aTypeName = "Shape";
+ break;
+ default:
+ aTypeName = "Shape of unknown type";
+ }
+
+ return aTypeName;
+}
+
+//=============================================================================
+/*!
+ * NumberOfSubShapes
+ */
+//=============================================================================
+Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
+ (Handle(GEOM_Object) theShape,
+ const Standard_Integer theShapeType)
+{
+ SetErrorCode(KO);
+ Standard_Integer nbShapes = 0;
+
+ if (theShape.IsNull()) return -1;
+ TopoDS_Shape aShape = theShape->GetValue();
+ if (aShape.IsNull()) return -1;
+
+ /*
+ TopTools_MapOfShape mapShape;
+
+ if (aShape.ShapeType() == TopAbs_COMPOUND &&
+ (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
+ TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
+ TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
+ TopoDS_Iterator It (aShape, Standard_True, Standard_True);
+ for (; It.More(); It.Next()) {
+ if (mapShape.Add(It.Value())) {
+ if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
+ TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
+ nbShapes++;
+ }
+ }
+ }
+ } else {
+ TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
+ for (; exp.More(); exp.Next())
+ if (mapShape.Add(exp.Current()))
+ nbShapes++;
+ }
+ */
+
+ 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()]++;
+
+ 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()]++;
+ }
+ }
+ }
+
+ if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
+ nbShapes = aMapOfShape.Extent();
+ else
+ nbShapes = nbTypes[theShapeType];
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return -1;
+ }
+
+ SetErrorCode(OK);
+ return nbShapes;
+}
+
+//=============================================================================
+/*!
+ * ReverseShape
+ */
+//=============================================================================
+Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull()) return NULL;
+
+ //Add a new reversed object
+ Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
+
+ //Add a new Revese function
+ Handle(GEOM_Function) aFunction;
+ aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
+ if (aFunction.IsNull()) return NULL;
+
+ //Check if the function is set correctly
+ if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
+
+ GEOMImpl_IShapes aSI (aFunction);
+
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (aRefShape.IsNull()) return NULL;
+
+ aSI.SetBase(aRefShape);
+
+ //Compute the sub-shape value
+ try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+ OCC_CATCH_SIGNALS;
+#endif
+ if (!GetSolver()->ComputeFunction(aFunction)) {
+ SetErrorCode("Shape driver failed to reverse shape");
+ return NULL;
+ }
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return NULL;
+ }
+
+ //Make a Python command
+ GEOM::TPythonDump(aFunction) << aReversed
+ << " = geompy.ChangeOrientation(" << theShape << ")";
+
+ SetErrorCode(OK);
+ return aReversed;
+}
+
+//=============================================================================
+/*!
+ * GetFreeFacesIDs
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
+ (Handle(GEOM_Object) theShape)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull()) return NULL;
+ TopoDS_Shape aShape = theShape->GetValue();
+ if (aShape.IsNull()) return NULL;
+
+ Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
+
+ TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
+ GEOMImpl_Block6Explorer::MapShapesAndAncestors
+ (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
+
+ Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
+
+ if (nbFaces == 0) {
+ SetErrorCode("The given shape has no faces");
+ return aSeq;
+ }
+
+ TopTools_IndexedMapOfShape anIndices;
+ TopExp::MapShapes(aShape, anIndices);
+
+ Standard_Integer id;
+ for (; ind <= nbFaces; ind++) {
+ if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
+ id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
+ aSeq->Append(id);
+ }
+ }
+
+ //The explode doesn't change object so no new function is required.
+ Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
+
+ //Make a Python command
+ GEOM::TPythonDump(aFunction, /*append=*/true)
+ << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=======================================================================
+//function : GetSharedShapes
+//purpose :
+//=======================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
+ (Handle(GEOM_Object) theShape1,
+ Handle(GEOM_Object) theShape2,
+ const Standard_Integer theShapeType)
+{
+ SetErrorCode(KO);
+
+ if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
+
+ TopoDS_Shape aShape1 = theShape1->GetValue();
+ TopoDS_Shape aShape2 = theShape2->GetValue();
+
+ if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
+
+ TopTools_IndexedMapOfShape anIndices;
+ TopExp::MapShapes(aShape1, anIndices);
+ Handle(TColStd_HArray1OfInteger) anArray;
+
+ TopTools_IndexedMapOfShape mapShape1;
+ TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
+
+ Handle(GEOM_Object) anObj;
+ Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+ TCollection_AsciiString anAsciiList, anEntry;
+
+ TopTools_MapOfShape mapShape2;
+ TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
+ for (; exp.More(); exp.Next()) {
+ TopoDS_Shape aSS = exp.Current();
+ if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
+ anArray = new TColStd_HArray1OfInteger(1,1);
+ anArray->SetValue(1, anIndices.FindIndex(aSS));
+ anObj = GetEngine()->AddSubShape(theShape1, anArray);
+ aSeq->Append(anObj);
+
+ // for python command
+ TDF_Tool::Entry(anObj->GetEntry(), anEntry);
+ anAsciiList += anEntry;
+ anAsciiList += ",";
+ }
+ }
+
+ if (aSeq->IsEmpty()) {
+ SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
+ return aSeq;
+ }
+
+ //Make a Python command
+ anAsciiList.Trunc(anAsciiList.Length() - 1);
+
+ Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+ GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
+ << "] = geompy.GetSharedShapes(" << theShape1 << ", "
+ << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
+ const GEOMAlgo_State theState)
+{
+ switch (theState) {
+ case GEOMAlgo_ST_IN:
+ theDump << "geompy.GEOM.ST_IN";
+ break;
+ case GEOMAlgo_ST_OUT:
+ theDump << "geompy.GEOM.ST_OUT";
+ break;
+ case GEOMAlgo_ST_ON:
+ theDump << "geompy.GEOM.ST_ON";
+ break;
+ case GEOMAlgo_ST_ONIN:
+ theDump << "geompy.GEOM.ST_ONIN";
+ break;
+ case GEOMAlgo_ST_ONOUT:
+ theDump << "geompy.GEOM.ST_ONOUT";
+ break;
+ default:
+ theDump << "geompy.GEOM.ST_UNKNOWN";
+ break;
+ }
+ return theDump;
+}
+
+//=======================================================================
+//function : checkTypeShapesOn
+/*!
+ * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
+ * \param theShapeType - the shape type to check
+ * \retval bool - result of the check
+ */
+//=======================================================================
+bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
+{
+ if (theShapeType != TopAbs_VERTEX &&
+ theShapeType != TopAbs_EDGE &&
+ theShapeType != TopAbs_FACE &&
+ theShapeType != TopAbs_SOLID) {
+ SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
+ return false;
+ }
+ return true;
+}
+
+//=======================================================================
+//function : makePlane
+ /*!
+ * \brief Creates Geom_Plane
+ * \param theAx1 - shape object defining plane parameters
+ * \retval Handle(Geom_Surface) - resulting surface
+ */
+//=======================================================================
+Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
+{
+ if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
+ TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
+ TopoDS_Vertex V1, V2;
+ TopExp::Vertices(anEdge, V1, V2, Standard_True);
+ if (V1.IsNull() || V2.IsNull()) {
+ SetErrorCode("Bad edge given for the plane normal vector");
+ return NULL;
+ }
+ gp_Pnt aLoc = BRep_Tool::Pnt(V1);
+ gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
+ if (aVec.Magnitude() < Precision::Confusion()) {
+ SetErrorCode("Vector with null magnitude given");
+ return NULL;
+ }
+ return new Geom_Plane(aLoc, aVec);
+}
+
+//=======================================================================
+//function : makeCylinder
+ /*!
+ * \brief Creates Geom_CylindricalSurface
+ * \param theAx1 - edge defining cylinder axis
+ * \param theRadius - cylinder radius
+ * \retval Handle(Geom_Surface) - resulting surface
+ */
+//=======================================================================
+Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
+ const Standard_Real theRadius)
+{
+ //Axis of the cylinder
+ if (anAxis.ShapeType() != TopAbs_EDGE) {
+ SetErrorCode("Not an edge given for the axis");
+ return NULL;
+ }
+ TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
+ TopoDS_Vertex V1, V2;
+ TopExp::Vertices(anEdge, V1, V2, Standard_True);
+ if (V1.IsNull() || V2.IsNull()) {
+ SetErrorCode("Bad edge given for the axis");
+ return NULL;
+ }
+ gp_Pnt aLoc = BRep_Tool::Pnt(V1);
+ gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
+ if (aVec.Magnitude() < Precision::Confusion()) {
+ SetErrorCode("Vector with null magnitude given");
+ return NULL;
+ }
+
+ gp_Ax3 anAx3 (aLoc, aVec);
+ return new Geom_CylindricalSurface(anAx3, theRadius);
+}
+
+//=======================================================================
+//function : getShapesOnBoxIDs
+ /*!
+ * \brief Find IDs of subshapes complying with given status about surface
+ * \param theBox - the box to check state of subshapes against
+ * \param theShape - the shape to explore
+ * \param theShapeType - type of subshape of theShape
+ * \param theState - required state
+ * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
+ */
+//=======================================================================
+Handle(TColStd_HSequenceOfInteger)
+ GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
+ const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ GEOMAlgo_State theState)
+{
+ Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
+
+ TopoDS_Shape aBox = theBox->GetValue();
+ TopoDS_Shape aShape = theShape->GetValue();
+
+ // Check presence of triangulation, build if need
+ if (!CheckTriangulation(aShape)) {
+ SetErrorCode("Cannot build triangulation on the shape");
+ return aSeqOfIDs;
+ }
+
+ // Call algo
+ GEOMAlgo_FinderShapeOn2 aFinder;
+ Standard_Real aTol = 0.0001; // default value
+
+ Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
+ aClsfBox->SetBox(aBox);
+
+ aFinder.SetShape(aShape);
+ aFinder.SetTolerance(aTol);
+ aFinder.SetClsf(aClsfBox);
+ aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
+ aFinder.SetState(theState);
+ aFinder.Perform();
+
+ // Interprete results
+ Standard_Integer iErr = aFinder.ErrorStatus();
+ // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
+ if (iErr) {
+ MESSAGE(" iErr : " << iErr);
+ TCollection_AsciiString aMsg (" iErr : ");
+ aMsg += TCollection_AsciiString(iErr);
+ SetErrorCode(aMsg);
+ return aSeqOfIDs;
+ }
+ Standard_Integer iWrn = aFinder.WarningStatus();
+ // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
+ if (iWrn) {
+ MESSAGE(" *** iWrn : " << iWrn);
+ }
+
+ const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
+
+ if (listSS.Extent() < 1) {
+ //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
+ SetErrorCode(NOT_FOUND_ANY); // NPAL18017
+ return aSeqOfIDs;
+ }
+
+ // Fill sequence of object IDs
+ aSeqOfIDs = new TColStd_HSequenceOfInteger;
+
+ TopTools_IndexedMapOfShape anIndices;
+ TopExp::MapShapes(aShape, anIndices);
+
+ TopTools_ListIteratorOfListOfShape itSub (listSS);
+ for (int index = 1; itSub.More(); itSub.Next(), ++index) {
+ int id = anIndices.FindIndex(itSub.Value());
+ aSeqOfIDs->Append(id);
+ }
+
+ return aSeqOfIDs;
+}
+
+//=======================================================================
+//function : GetShapesOnBoxIDs
+/*!
+ * \brief Find subshapes complying with given status about surface
+ * \param theBox - the box to check state of subshapes against
+ * \param theShape - the shape to explore
+ * \param theShapeType - type of subshape of theShape
+ * \param theState - required state
+ * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
+ */
+//=======================================================================
+Handle(TColStd_HSequenceOfInteger)
+ GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
+ const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ GEOMAlgo_State theState)
+{
+ // Find subshapes ids
+ Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
+ getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
+ if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
+ return NULL;
+
+ // The GetShapesOnBox() doesn't change object so no new function is required.
+ Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
+
+ // Make a Python command
+ GEOM::TPythonDump(aFunction)
+ << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
+ << theBox << ", "
+ << theShape << ", "
+ << TopAbs_ShapeEnum(theShapeType) << ", "
+ << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeqOfIDs;
+}
+
+//=======================================================================
+//function : GetShapesOnBox
+/*!
+ * \brief Find subshapes complying with given status about surface
+ * \param theBox - the box to check state of subshapes against
+ * \param theShape - the shape to explore
+ * \param theShapeType - type of subshape of theShape
+ * \param theState - required state
+ * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
+ */
+//=======================================================================
+Handle(TColStd_HSequenceOfTransient)
+ GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
+ const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ GEOMAlgo_State theState)
+{
+ // Find subshapes ids
+ Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
+ getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
+ if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
+ return NULL;
+
+ // Find objects by indices
+ TCollection_AsciiString anAsciiList;
+ Handle(TColStd_HSequenceOfTransient) aSeq;
+ aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
+ if ( aSeq.IsNull() || aSeq->IsEmpty() )
+ return NULL;
+
+ // Make a Python command
+
+ Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
+ Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+ GEOM::TPythonDump(aFunction)
+ << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
+ << theBox << ", "
+ << theShape << ", "
+ << TopAbs_ShapeEnum(theShapeType) << ", "
+ << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=======================================================================
+//function : getShapesOnShapeIDs
+/*!
+ * \brief Find IDs of subshapes complying with given status about surface
+ * \param theCheckShape - the shape to check state of subshapes against
+ * \param theShape - the shape to explore
+ * \param theShapeType - type of subshape of theShape
+ * \param theState - required state
+ * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
+ */
+//=======================================================================
+Handle(TColStd_HSequenceOfInteger)
+ GEOMImpl_IShapesOperations::getShapesOnShapeIDs
+ (const Handle(GEOM_Object)& theCheckShape,
+ const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ GEOMAlgo_State theState)
+{
+ Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
+
+ TopoDS_Shape aCheckShape = theCheckShape->GetValue();
+ TopoDS_Shape aShape = theShape->GetValue();
+ TopTools_ListOfShape res;
+
+ // Check presence of triangulation, build if need
+ if (!CheckTriangulation(aShape)) {
+ SetErrorCode("Cannot build triangulation on the shape");
+ return aSeqOfIDs;
+ }
+
+ // Call algo
+ GEOMAlgo_FinderShapeOn2 aFinder;
+ Standard_Real aTol = 0.0001; // default value
+
+ Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
+ aClsfSolid->SetShape(aCheckShape);
+
+ aFinder.SetShape(aShape);
+ aFinder.SetTolerance(aTol);
+ aFinder.SetClsf(aClsfSolid);
+ aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
+ aFinder.SetState(theState);
+ aFinder.Perform();
+
+ // Interprete results
+ Standard_Integer iErr = aFinder.ErrorStatus();
+ // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
+ if (iErr) {
+ if (iErr == 41) {
+ SetErrorCode("theCheckShape must be a solid");
+ }
+ else {
+ MESSAGE(" iErr : " << iErr);
+ TCollection_AsciiString aMsg (" iErr : ");
+ aMsg += TCollection_AsciiString(iErr);
+ SetErrorCode(aMsg);
+ }
+ return aSeqOfIDs;
+ }
+ Standard_Integer iWrn = aFinder.WarningStatus();
+ // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
+ if (iWrn) {
+ MESSAGE(" *** iWrn : " << iWrn);
+ }
+
+ const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
+
+ if (listSS.Extent() < 1) {
+ //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
+ SetErrorCode(NOT_FOUND_ANY); // NPAL18017
+ }
+
+ // Fill sequence of object IDs
+ aSeqOfIDs = new TColStd_HSequenceOfInteger;
+
+ TopTools_IndexedMapOfShape anIndices;
+ TopExp::MapShapes(aShape, anIndices);
+
+ TopTools_ListIteratorOfListOfShape itSub (listSS);
+ for (int index = 1; itSub.More(); itSub.Next(), ++index) {
+ int id = anIndices.FindIndex(itSub.Value());
+ aSeqOfIDs->Append(id);
+ }
+
+ return aSeqOfIDs;
+}
+
+//=======================================================================
+//function : GetShapesOnShapeIDs
+/*!
+ * \brief Find subshapes complying with given status about surface
+ * \param theCheckShape - the shape to check state of subshapes against
+ * \param theShape - the shape to explore
+ * \param theShapeType - type of subshape of theShape
+ * \param theState - required state
+ * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
+ */
+//=======================================================================
+Handle(TColStd_HSequenceOfInteger)
+ GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
+ (const Handle(GEOM_Object)& theCheckShape,
+ const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ GEOMAlgo_State theState)
+{
+ Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
+ getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
+
+ if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
+ return NULL;
+
+ // The GetShapesOnShape() doesn't change object so no new function is required.
+ Handle(GEOM_Function) aFunction =
+ GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
+
+ // Make a Python command
+ GEOM::TPythonDump(aFunction)
+ << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
+ << theCheckShape << ", "
+ << theShape << ", "
+ << TopAbs_ShapeEnum(theShapeType) << ", "
+ << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeqOfIDs;
+}
+
+//=======================================================================
+//function : GetShapesOnShape
+/*!
+ * \brief Find subshapes complying with given status about surface
+ * \param theCheckShape - the shape to check state of subshapes against
+ * \param theShape - the shape to explore
+ * \param theShapeType - type of subshape of theShape
+ * \param theState - required state
+ * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
+ */
+//=======================================================================
+Handle(TColStd_HSequenceOfTransient)
+ GEOMImpl_IShapesOperations::GetShapesOnShape
+ (const Handle(GEOM_Object)& theCheckShape,
+ const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ GEOMAlgo_State theState)
+{
+ Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
+ getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
+ if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
+ return NULL;
+
+ // Find objects by indices
+ TCollection_AsciiString anAsciiList;
+ Handle(TColStd_HSequenceOfTransient) aSeq;
+ aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
+
+ if ( aSeq.IsNull() || aSeq->IsEmpty() )
+ return NULL;
+
+ // Make a Python command
+
+ Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
+ Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+ GEOM::TPythonDump(aFunction)
+ << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
+ << theCheckShape << ", "
+ << theShape << ", "
+ << TopAbs_ShapeEnum(theShapeType) << ", "
+ << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=======================================================================
+//function : GetShapesOnShapeAsCompound
+//=======================================================================
+Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
+ (const Handle(GEOM_Object)& theCheckShape,
+ const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ GEOMAlgo_State theState)
+{
+ Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
+ getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
+
+ if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
+ return NULL;
+
+ // Find objects by indices
+ TCollection_AsciiString anAsciiList;
+ Handle(TColStd_HSequenceOfTransient) aSeq;
+ aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
+
+ if ( aSeq.IsNull() || aSeq->IsEmpty() )
+ return NULL;
+
+ TopoDS_Compound aCompound;
+ BRep_Builder B;
+ B.MakeCompound(aCompound);
+ int i = 1;
+ for(; i<=aSeq->Length(); i++) {
+ Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
+ TopoDS_Shape aShape_i = anObj->GetValue();
+ B.Add(aCompound,aShape_i);
+ }
+
+ //Add a new result object
+ Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
+ Handle(GEOM_Function) aFunction =
+ aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
+ aFunction->SetValue(aCompound);
+
+ GEOM::TPythonDump(aFunction)
+ << aRes << " = geompy.GetShapesOnShapeAsCompound("
+ << theCheckShape << ", "
+ << theShape << ", "
+ << TopAbs_ShapeEnum(theShapeType) << ", "
+ << theState << ")";
+
+ SetErrorCode(OK);
+
+ return aRes;
+}
+
+//=======================================================================
+//function : getShapesOnSurfaceIDs
+ /*!
+ * \brief Find IDs of subshapes complying with given status about surface
+ * \param theSurface - the surface to check state of subshapes against
+ * \param theShape - the shape to explore
+ * \param theShapeType - type of subshape of theShape
+ * \param theState - required state
+ * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
+ */
+//=======================================================================
+Handle(TColStd_HSequenceOfInteger)
+ GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
+ const TopoDS_Shape& theShape,
+ TopAbs_ShapeEnum theShapeType,
+ GEOMAlgo_State theState)
+{
+ Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
+
+ // Check presence of triangulation, build if need
+ if (!CheckTriangulation(theShape)) {
+ SetErrorCode("Cannot build triangulation on the shape");
+ return aSeqOfIDs;
+ }
+
+ // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
+ // Compute tolerance
+ Standard_Real T, VertMax = -RealLast();
+ try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+ OCC_CATCH_SIGNALS;
+#endif
+ for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
+ TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
+ T = BRep_Tool::Tolerance(Vertex);
+ if (T > VertMax)
+ VertMax = T;
+ }
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return aSeqOfIDs;
+ }
+ // END: Mantis issue 0020961
+
+ // Call algo
+ GEOMAlgo_FinderShapeOn1 aFinder;
+ //Standard_Real aTol = 0.0001; // default value
+ Standard_Real aTol = VertMax; // Mantis issue 0020961
+
+ aFinder.SetShape(theShape);
+ aFinder.SetTolerance(aTol);
+ aFinder.SetSurface(theSurface);
+ aFinder.SetShapeType(theShapeType);
+ aFinder.SetState(theState);
+
+ // Sets the minimal number of inner points for the faces that do not have own
+ // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
+ // Default value=3
+ aFinder.SetNbPntsMin(3);
+ // Sets the maximal number of inner points for edges or faces.
+ // It is usefull for the cases when this number is very big (e.g =2000) to improve
+ // the performance. If this value =0, all inner points will be taken into account.
+ // Default value=0
+ aFinder.SetNbPntsMax(100);
+
+ aFinder.Perform();
+
+ // Interprete results
+ Standard_Integer iErr = aFinder.ErrorStatus();
+ // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
+ if (iErr) {
+ MESSAGE(" iErr : " << iErr);
+ TCollection_AsciiString aMsg (" iErr : ");
+ aMsg += TCollection_AsciiString(iErr);
+ SetErrorCode(aMsg);
+ return aSeqOfIDs;
+ }
+ Standard_Integer iWrn = aFinder.WarningStatus();
+ // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
+ if (iWrn) {
+ MESSAGE(" *** iWrn : " << iWrn);
+ }
+
+ const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
+
+ if (listSS.Extent() < 1) {
+ //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
+ SetErrorCode(NOT_FOUND_ANY); // NPAL18017
+ return aSeqOfIDs;
+ }
+
+ // Fill sequence of object IDs
+ aSeqOfIDs = new TColStd_HSequenceOfInteger;
+
+ TopTools_IndexedMapOfShape anIndices;
+ TopExp::MapShapes(theShape, anIndices);
+
+ TopTools_ListIteratorOfListOfShape itSub (listSS);
+ for (int index = 1; itSub.More(); itSub.Next(), ++index) {
+ int id = anIndices.FindIndex(itSub.Value());
+ aSeqOfIDs->Append(id);
+ }
+
+ return aSeqOfIDs;
+}
+
+//=======================================================================
+//function : getObjectsShapesOn
+/*!
+ * \brief Find shape objects and their entries by their ids
+ * \param theShapeIDs - incoming shape ids
+ * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
+ * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
+ */
+//=======================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
+ getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
+ const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
+ TCollection_AsciiString & theShapeEntries)
+{
+ Handle(TColStd_HSequenceOfTransient) aSeq;
+
+ if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
+ {
+ aSeq = new TColStd_HSequenceOfTransient;
+ Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
+ TCollection_AsciiString anEntry;
+ for ( int i = 1; i <= theShapeIDs->Length(); ++i )
+ {
+ anArray->SetValue(1, theShapeIDs->Value( i ));
+ Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
+ aSeq->Append( anObj );
+
+ TDF_Tool::Entry(anObj->GetEntry(), anEntry);
+ if ( i != 1 ) theShapeEntries += ",";
+ theShapeEntries += anEntry;
+ }
+ }
+ return aSeq;
+}
+
+//=======================================================================
+//function : getShapesOnSurface
+/*!
+ * \brief Find subshapes complying with given status about surface
+ * \param theSurface - the surface to check state of subshapes against
+ * \param theShape - the shape to explore
+ * \param theShapeType - type of subshape of theShape
+ * \param theState - required state
+ * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
+ * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
+ */
+//=======================================================================
+Handle(TColStd_HSequenceOfTransient)
+ GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
+ const Handle(GEOM_Object)& theShape,
+ TopAbs_ShapeEnum theShapeType,
+ GEOMAlgo_State theState,
+ TCollection_AsciiString & theShapeEntries)
+{
+ // Find subshapes ids
+ Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
+ getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
+ if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
+ return NULL;
+
+ return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
+}
+
+//=============================================================================
+/*!
+ * GetShapesOnPlane
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
+ (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theAx1,
+ const GEOMAlgo_State theState)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull() || theAx1.IsNull()) return NULL;
+
+ TopoDS_Shape aShape = theShape->GetValue();
+ TopoDS_Shape anAx1 = theAx1->GetValue();
+
+ if (aShape.IsNull() || anAx1.IsNull()) return NULL;
+
+ TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+ if ( !checkTypeShapesOn( theShapeType ))
+ return NULL;
+
+ // Create plane
+ Handle(Geom_Surface) aPlane = makePlane( anAx1 );
+ if ( aPlane.IsNull() )
+ return NULL;
+
+ // Find objects
+ TCollection_AsciiString anAsciiList;
+ Handle(TColStd_HSequenceOfTransient) aSeq;
+ aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
+ if ( aSeq.IsNull() || aSeq->Length() == 0 )
+ return NULL;
+
+ // Make a Python command
+
+ Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
+ Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+ GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
+ << "] = geompy.GetShapesOnPlane(" << theShape << ", "
+ << aShapeType << ", " << theAx1 << ", " << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ * GetShapesOnPlaneWithLocation
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
+ (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theAx1,
+ const Handle(GEOM_Object)& thePnt,
+ const GEOMAlgo_State theState)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
+
+ TopoDS_Shape aShape = theShape->GetValue();
+ TopoDS_Shape anAx1 = theAx1->GetValue();
+ TopoDS_Shape anPnt = thePnt->GetValue();
+
+ if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
+
+ TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+ if ( !checkTypeShapesOn( theShapeType ))
+ return NULL;
+
+ // Create plane
+ if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
+ TopoDS_Vertex V1, V2, V3;
+ TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
+ TopExp::Vertices(anEdge, V1, V2, Standard_True);
+
+ if (V1.IsNull() || V2.IsNull()) {
+ SetErrorCode("Bad edge given for the plane normal vector");
+ return NULL;
+ }
+ V3 = TopoDS::Vertex(anPnt);
+
+ if(V3.IsNull()) {
+ SetErrorCode("Bad vertex given for the plane location");
+ return NULL;
+ }
+ gp_Pnt aLoc = BRep_Tool::Pnt(V3);
+ gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
+
+ if (aVec.Magnitude() < Precision::Confusion()) {
+ SetErrorCode("Vector with null magnitude given");
+ return NULL;
+ }
+ Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
+
+ if ( aPlane.IsNull() )
+ return NULL;
+
+ // Find objects
+ TCollection_AsciiString anAsciiList;
+ Handle(TColStd_HSequenceOfTransient) aSeq;
+ aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
+ if ( aSeq.IsNull() || aSeq->Length() == 0 )
+ return NULL;
+
+ // Make a Python command
+
+ Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
+ Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+ GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
+ << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
+ << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ * GetShapesOnCylinder
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
+ (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theAxis,
+ const Standard_Real theRadius,
+ const GEOMAlgo_State theState)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull() || theAxis.IsNull()) return NULL;
+
+ TopoDS_Shape aShape = theShape->GetValue();
+ TopoDS_Shape anAxis = theAxis->GetValue();
+
+ if (aShape.IsNull() || anAxis.IsNull()) return NULL;
+
+ TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+ if ( !checkTypeShapesOn( aShapeType ))
+ return NULL;
+
+ // Create a cylinder surface
+ Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
+ if ( aCylinder.IsNull() )
+ return NULL;
+
+ // Find objects
+ TCollection_AsciiString anAsciiList;
+ Handle(TColStd_HSequenceOfTransient) aSeq;
+ aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
+ if ( aSeq.IsNull() || aSeq->Length() == 0 )
+ return NULL;
+
+ // Make a Python command
+
+ Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
+ Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+ GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
+ << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
+ << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ * GetShapesOnCylinderWithLocation
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
+ (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theAxis,
+ const Handle(GEOM_Object)& thePnt,
+ const Standard_Real theRadius,
+ const GEOMAlgo_State theState)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
+
+ TopoDS_Shape aShape = theShape->GetValue();
+ TopoDS_Shape anAxis = theAxis->GetValue();
+ TopoDS_Shape aPnt = thePnt->GetValue();
+
+ if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
+
+ if (aPnt.ShapeType() != TopAbs_VERTEX )
+ {
+ SetErrorCode("Bottom location point must be vertex");
+ return NULL;
+ }
+
+ TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+ if ( !checkTypeShapesOn( aShapeType ))
+ return NULL;
+
+ // Create a cylinder surface
+ Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
+ if ( aCylinder.IsNull() )
+ return NULL;
+
+ // translate the surface
+ Handle(Geom_CylindricalSurface) aCylSurface =
+ Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
+ if ( aCylSurface.IsNull() )
+ {
+ SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
+ return NULL;
+ }
+ gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
+ gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
+ aCylinder->Translate( fromLoc, toLoc );
+
+ // Find objects
+ TCollection_AsciiString anAsciiList;
+ Handle(TColStd_HSequenceOfTransient) aSeq;
+ aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
+ if ( aSeq.IsNull() || aSeq->Length() == 0 )
+ return NULL;
+
+ // Make a Python command
+
+ Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
+ Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+ GEOM::TPythonDump(aFunction)
+ << "[" << anAsciiList.ToCString()
+ << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
+ << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ * GetShapesOnSphere
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
+ (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theCenter,
+ const Standard_Real theRadius,
+ const GEOMAlgo_State theState)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull() || theCenter.IsNull()) return NULL;
+
+ TopoDS_Shape aShape = theShape->GetValue();
+ TopoDS_Shape aCenter = theCenter->GetValue();
+
+ if (aShape.IsNull() || aCenter.IsNull()) return NULL;
+
+ TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+ if ( !checkTypeShapesOn( aShapeType ))
+ return NULL;
+
+ // Center of the sphere
+ if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
+ gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
+
+ gp_Ax3 anAx3 (aLoc, gp::DZ());
+ Handle(Geom_SphericalSurface) aSphere =
+ new Geom_SphericalSurface(anAx3, theRadius);
+
+ // Find objects
+ TCollection_AsciiString anAsciiList;
+ Handle(TColStd_HSequenceOfTransient) aSeq;
+ aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
+ if ( aSeq.IsNull() || aSeq->Length() == 0 )
+ return NULL;
+
+ // Make a Python command
+
+ Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
+ Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+ GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
+ << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
+ << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ * GetShapesOnPlaneIDs
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
+ (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theAx1,
+ const GEOMAlgo_State theState)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull() || theAx1.IsNull()) return NULL;
+
+ TopoDS_Shape aShape = theShape->GetValue();
+ TopoDS_Shape anAx1 = theAx1->GetValue();
+
+ if (aShape.IsNull() || anAx1.IsNull()) return NULL;
+
+ TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+ if ( !checkTypeShapesOn( aShapeType ))
+ return NULL;
+
+ // Create plane
+ Handle(Geom_Surface) aPlane = makePlane( anAx1 );
+ if ( aPlane.IsNull() )
+ return NULL;
+
+ // Find object IDs
+ Handle(TColStd_HSequenceOfInteger) aSeq;
+ aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
+
+ // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
+ Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
+
+ // Make a Python command
+ GEOM::TPythonDump(aFunction, /*append=*/true)
+ << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
+ << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ * GetShapesOnPlaneWithLocationIDs
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
+ (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theAx1,
+ const Handle(GEOM_Object)& thePnt,
+ const GEOMAlgo_State theState)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
+
+ TopoDS_Shape aShape = theShape->GetValue();
+ TopoDS_Shape anAx1 = theAx1->GetValue();
+ TopoDS_Shape anPnt = thePnt->GetValue();
+
+ if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
+
+ TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+ if ( !checkTypeShapesOn( aShapeType ))
+ return NULL;
+
+ // Create plane
+ if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
+ TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
+ TopoDS_Vertex V1, V2, V3;
+ TopExp::Vertices(anEdge, V1, V2, Standard_True);
+ if (V1.IsNull() || V2.IsNull()) {
+ SetErrorCode("Bad edge given for the plane normal vector");
+ return NULL;
+ }
+ V3 = TopoDS::Vertex(anPnt);
+ if(V3.IsNull()) {
+ SetErrorCode("Bad vertex given for the plane location");
+ return NULL;
+ }
+ gp_Pnt aLoc = BRep_Tool::Pnt(V3);
+ gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
+ if (aVec.Magnitude() < Precision::Confusion()) {
+ SetErrorCode("Vector with null magnitude given");
+ return NULL;
+ }
+
+ Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
+ if ( aPlane.IsNull() )
+ return NULL;
+
+ // Find object IDs
+ Handle(TColStd_HSequenceOfInteger) aSeq;
+ aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
+
+ // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
+ Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
+
+ // Make a Python command
+ GEOM::TPythonDump(aFunction, /*append=*/true)
+ << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
+ << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ * GetShapesOnCylinderIDs
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
+ (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theAxis,
+ const Standard_Real theRadius,
+ const GEOMAlgo_State theState)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull() || theAxis.IsNull()) return NULL;
+
+ TopoDS_Shape aShape = theShape->GetValue();
+ TopoDS_Shape anAxis = theAxis->GetValue();
+
+ if (aShape.IsNull() || anAxis.IsNull()) return NULL;
+
+ TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+ if ( !checkTypeShapesOn( aShapeType ))
+ return NULL;
+
+ // Create a cylinder surface
+ Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
+ if ( aCylinder.IsNull() )
+ return NULL;
+
+ // Find object IDs
+ Handle(TColStd_HSequenceOfInteger) aSeq;
+ aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
+
+ // The GetShapesOnCylinder() doesn't change object so no new function is required.
+ Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
+
+ // Make a Python command
+ GEOM::TPythonDump(aFunction, /*append=*/true)
+ << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
+ << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
+ << theRadius << ", " << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ * GetShapesOnCylinderWithLocationIDs
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
+ (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theAxis,
+ const Handle(GEOM_Object)& thePnt,
+ const Standard_Real theRadius,
+ const GEOMAlgo_State theState)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
+
+ TopoDS_Shape aShape = theShape->GetValue();
+ TopoDS_Shape anAxis = theAxis->GetValue();
+ TopoDS_Shape aPnt = thePnt->GetValue();
+
+ if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
+
+ if (aPnt.ShapeType() != TopAbs_VERTEX )
+ {
+ SetErrorCode("Bottom location point must be vertex");
+ return NULL;
+ }
+
+ TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+ if ( !checkTypeShapesOn( aShapeType ))
+ return NULL;
+
+ // Create a cylinder surface
+ Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
+ if ( aCylinder.IsNull() )
+ return NULL;
+
+ // translate the surface
+ Handle(Geom_CylindricalSurface) aCylSurface =
+ Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
+ if ( aCylSurface.IsNull() )
+ {
+ SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
+ return NULL;
+ }
+ gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
+ gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
+ aCylinder->Translate( fromLoc, toLoc );
+
+ // Find object IDs
+ Handle(TColStd_HSequenceOfInteger) aSeq;
+ aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
+
+ // The GetShapesOnCylinder() doesn't change object so no new function is required.
+ Handle(GEOM_Function) aFunction =
+ GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
+
+ // Make a Python command
+ GEOM::TPythonDump(aFunction, /*append=*/true)
+ << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
+ << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
+ << thePnt << ", " << theRadius << ", " << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ * GetShapesOnSphereIDs
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
+ (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theCenter,
+ const Standard_Real theRadius,
+ const GEOMAlgo_State theState)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull() || theCenter.IsNull()) return NULL;
+
+ TopoDS_Shape aShape = theShape->GetValue();
+ TopoDS_Shape aCenter = theCenter->GetValue();
+
+ if (aShape.IsNull() || aCenter.IsNull()) return NULL;
+
+ TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+ if ( !checkTypeShapesOn( aShapeType ))
+ return NULL;
+
+ // Center of the sphere
+ if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
+ gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
+
+ gp_Ax3 anAx3 (aLoc, gp::DZ());
+ Handle(Geom_SphericalSurface) aSphere =
+ new Geom_SphericalSurface(anAx3, theRadius);
+
+ // Find object IDs
+ Handle(TColStd_HSequenceOfInteger) aSeq;
+ aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
+
+ // The GetShapesOnSphere() doesn't change object so no new function is required.
+ Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
+
+ // Make a Python command
+ GEOM::TPythonDump(aFunction, /*append=*/true)
+ << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
+ << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
+ << theRadius << ", " << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=======================================================================
+//function : getShapesOnQuadrangleIDs
+ /*!
+ * \brief Find IDs of subshapes complying with given status about quadrangle
+ * \param theShape - the shape to explore
+ * \param theShapeType - type of subshape of theShape
+ * \param theTopLeftPoint - top left quadrangle corner
+ * \param theTopRigthPoint - top right quadrangle corner
+ * \param theBottomLeftPoint - bottom left quadrangle corner
+ * \param theBottomRigthPoint - bottom right quadrangle corner
+ * \param theState - required state
+ * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
+ */
+//=======================================================================
+Handle(TColStd_HSequenceOfInteger)
+ GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theTopLeftPoint,
+ const Handle(GEOM_Object)& theTopRigthPoint,
+ const Handle(GEOM_Object)& theBottomLeftPoint,
+ const Handle(GEOM_Object)& theBottomRigthPoint,
+ const GEOMAlgo_State theState)
+{
+ SetErrorCode(KO);
+
+ if ( theShape.IsNull() ||
+ theTopLeftPoint.IsNull() ||
+ theTopRigthPoint.IsNull() ||
+ theBottomLeftPoint.IsNull() ||
+ theBottomRigthPoint.IsNull() )
+ return NULL;
+
+ TopoDS_Shape aShape = theShape->GetValue();
+ TopoDS_Shape aTL = theTopLeftPoint->GetValue();
+ TopoDS_Shape aTR = theTopRigthPoint->GetValue();
+ TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
+ TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
+
+ if (aShape.IsNull() ||
+ aTL.IsNull() ||
+ aTR.IsNull() ||
+ aBL.IsNull() ||
+ aBR.IsNull() ||
+ aTL.ShapeType() != TopAbs_VERTEX ||
+ aTR.ShapeType() != TopAbs_VERTEX ||
+ aBL.ShapeType() != TopAbs_VERTEX ||
+ aBR.ShapeType() != TopAbs_VERTEX )
+ return NULL;
+
+ TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+ if ( !checkTypeShapesOn( aShapeType ))
+ return NULL;
+
+ Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
+
+ // Check presence of triangulation, build if need
+ if (!CheckTriangulation(aShape)) {
+ SetErrorCode("Cannot build triangulation on the shape");
+ return aSeqOfIDs;
+ }
+
+ // Call algo
+ gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
+ gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
+ gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
+ gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
+
+ GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
+ Standard_Real aTol = 0.0001; // default value
+
+ aFinder.SetShape(aShape);
+ aFinder.SetTolerance(aTol);
+ //aFinder.SetSurface(theSurface);
+ aFinder.SetShapeType(aShapeType);
+ aFinder.SetState(theState);
+
+ // Sets the minimal number of inner points for the faces that do not have own
+ // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
+ // Default value=3
+ aFinder.SetNbPntsMin(3);
+ // Sets the maximal number of inner points for edges or faces.
+ // It is usefull for the cases when this number is very big (e.g =2000) to improve
+ // the performance. If this value =0, all inner points will be taken into account.
+ // Default value=0
+ aFinder.SetNbPntsMax(100);
+
+ aFinder.Perform();
+
+ // Interprete results
+ Standard_Integer iErr = aFinder.ErrorStatus();
+ // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
+ if (iErr) {
+ MESSAGE(" iErr : " << iErr);
+ TCollection_AsciiString aMsg (" iErr : ");
+ aMsg += TCollection_AsciiString(iErr);
+ SetErrorCode(aMsg);
+ return aSeqOfIDs;
+ }
+ Standard_Integer iWrn = aFinder.WarningStatus();
+ // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
+ if (iWrn) {
+ MESSAGE(" *** iWrn : " << iWrn);
+ }
+
+ const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
+
+ if (listSS.Extent() < 1) {
+ //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
+ SetErrorCode(NOT_FOUND_ANY); // NPAL18017
+ return aSeqOfIDs;
+ }
+
+ // Fill sequence of object IDs
+ aSeqOfIDs = new TColStd_HSequenceOfInteger;
+
+ TopTools_IndexedMapOfShape anIndices;
+ TopExp::MapShapes(aShape, anIndices);
+
+ TopTools_ListIteratorOfListOfShape itSub (listSS);
+ for (int index = 1; itSub.More(); itSub.Next(), ++index) {
+ int id = anIndices.FindIndex(itSub.Value());
+ aSeqOfIDs->Append(id);
+ }
+ return aSeqOfIDs;
+}
+
+//=======================================================================
+//function : GetShapesOnQuadrangle
+ /*!
+ * \brief Find subshapes complying with given status about quadrangle
+ * \param theShape - the shape to explore
+ * \param theShapeType - type of subshape of theShape
+ * \param theTopLeftPoint - top left quadrangle corner
+ * \param theTopRigthPoint - top right quadrangle corner
+ * \param theBottomLeftPoint - bottom left quadrangle corner
+ * \param theBottomRigthPoint - bottom right quadrangle corner
+ * \param theState - required state
+ * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
+ */
+//=======================================================================
+Handle(TColStd_HSequenceOfTransient)
+ GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theTopLeftPoint,
+ const Handle(GEOM_Object)& theTopRigthPoint,
+ const Handle(GEOM_Object)& theBottomLeftPoint,
+ const Handle(GEOM_Object)& theBottomRigthPoint,
+ const GEOMAlgo_State theState)
+{
+ // Find indices
+ Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
+ getShapesOnQuadrangleIDs( theShape,
+ theShapeType,
+ theTopLeftPoint,
+ theTopRigthPoint,
+ theBottomLeftPoint,
+ theBottomRigthPoint,
+ theState);
+ if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
+ return NULL;
+
+ // Find objects by indices
+ TCollection_AsciiString anAsciiList;
+ Handle(TColStd_HSequenceOfTransient) aSeq;
+ aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
+ if ( aSeq.IsNull() || aSeq->IsEmpty() )
+ return NULL;
+
+ // Make a Python command
+
+ Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
+ Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+ GEOM::TPythonDump(aFunction)
+ << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
+ << theShape << ", "
+ << TopAbs_ShapeEnum(theShapeType) << ", "
+ << theTopLeftPoint << ", "
+ << theTopRigthPoint << ", "
+ << theBottomLeftPoint << ", "
+ << theBottomRigthPoint << ", "
+ << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=======================================================================
+//function : GetShapesOnQuadrangleIDs
+ /*!
+ * \brief Find IDs of subshapes complying with given status about quadrangle
+ * \param theShape - the shape to explore
+ * \param theShapeType - type of subshape of theShape
+ * \param theTopLeftPoint - top left quadrangle corner
+ * \param theTopRigthPoint - top right quadrangle corner
+ * \param theBottomLeftPoint - bottom left quadrangle corner
+ * \param theBottomRigthPoint - bottom right quadrangle corner
+ * \param theState - required state
+ * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
+ */
+//=======================================================================
+Handle(TColStd_HSequenceOfInteger)
+ GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theTopLeftPoint,
+ const Handle(GEOM_Object)& theTopRigthPoint,
+ const Handle(GEOM_Object)& theBottomLeftPoint,
+ const Handle(GEOM_Object)& theBottomRigthPoint,
+ const GEOMAlgo_State theState)
+{
+ // Find indices
+ Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
+ getShapesOnQuadrangleIDs( theShape,
+ theShapeType,
+ theTopLeftPoint,
+ theTopRigthPoint,
+ theBottomLeftPoint,
+ theBottomRigthPoint,
+ theState);
+ if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
+ return NULL;
+
+ // Make a Python command
+
+ // The GetShapesOnCylinder() doesn't change object so no new function is required.
+ Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
+ lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
+ lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
+ lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
+ Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
+
+ GEOM::TPythonDump(aFunction, /*append=*/true)
+ << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
+ << theShape << ", "
+ << TopAbs_ShapeEnum(theShapeType) << ", "
+ << theTopLeftPoint << ", "
+ << theTopRigthPoint << ", "
+ << theBottomLeftPoint << ", "
+ << theBottomRigthPoint << ", "
+ << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeqOfIDs;
+}