1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File : GEOMImpl_IShapesOperations.cxx
22 // Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
28 #include <Standard_Stream.hxx>
30 #include "GEOMImpl_IShapesOperations.hxx"
32 #include "GEOMImpl_Types.hxx"
34 #include "GEOMImpl_VectorDriver.hxx"
35 #include "GEOMImpl_ShapeDriver.hxx"
36 #include "GEOMImpl_CopyDriver.hxx"
37 #include "GEOMImpl_GlueDriver.hxx"
39 #include "GEOMImpl_IVector.hxx"
40 #include "GEOMImpl_IShapes.hxx"
41 #include "GEOMImpl_IGlue.hxx"
43 #include "GEOMImpl_Block6Explorer.hxx"
45 #include "GEOM_Function.hxx"
46 #include "GEOM_ISubShape.hxx"
47 #include "GEOM_PythonDump.hxx"
49 #include "GEOMAlgo_FinderShapeOn1.hxx"
50 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
51 #include "GEOMAlgo_FinderShapeOn2.hxx"
52 #include "GEOMAlgo_ClsfBox.hxx"
53 #include "GEOMAlgo_Gluer1.hxx"
54 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
55 #include "GEOMAlgo_CoupleOfShapes.hxx"
56 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
58 #include "utilities.h"
60 #include "Utils_ExceptHandlers.hxx"
62 #include <TFunction_DriverTable.hxx>
63 #include <TFunction_Driver.hxx>
64 #include <TFunction_Logbook.hxx>
65 #include <TDataStd_Integer.hxx>
66 #include <TDataStd_IntegerArray.hxx>
67 #include <TDF_Tool.hxx>
69 #include <BRepExtrema_ExtCF.hxx>
71 #include <BRep_Tool.hxx>
72 #include <BRep_Builder.hxx>
73 #include <BRepTools.hxx>
74 #include <BRepGProp.hxx>
75 #include <BRepAdaptor_Curve.hxx>
76 #include <BRepAdaptor_Surface.hxx>
77 #include <BRepBndLib.hxx>
78 #include <BRepBuilderAPI_MakeFace.hxx>
79 #include <BRepMesh_IncrementalMesh.hxx>
84 #include <TopoDS_Shape.hxx>
85 #include <TopoDS_Solid.hxx>
86 #include <TopoDS_Face.hxx>
87 #include <TopoDS_Edge.hxx>
88 #include <TopoDS_Vertex.hxx>
89 #include <TopoDS_Compound.hxx>
90 #include <TopoDS_Iterator.hxx>
91 #include <TopExp_Explorer.hxx>
92 #include <TopLoc_Location.hxx>
93 #include <TopTools_MapOfShape.hxx>
94 #include <TopTools_MapOfOrientedShape.hxx>
95 #include <TopTools_Array1OfShape.hxx>
96 #include <TopTools_ListIteratorOfListOfShape.hxx>
97 #include <TopTools_IndexedMapOfShape.hxx>
99 #include <Geom_Surface.hxx>
100 #include <Geom_Plane.hxx>
101 #include <Geom_SphericalSurface.hxx>
102 #include <Geom_CylindricalSurface.hxx>
103 #include <GeomAdaptor_Surface.hxx>
105 #include <GeomLib_Tool.hxx>
106 #include <Geom2d_Curve.hxx>
108 #include <Bnd_Box.hxx>
109 #include <GProp_GProps.hxx>
110 #include <gp_Pnt.hxx>
111 #include <gp_Lin.hxx>
112 #include <TColStd_ListOfInteger.hxx>
113 #include <TColStd_ListIteratorOfListOfInteger.hxx>
114 #include <TColStd_Array1OfReal.hxx>
115 #include <TColStd_HArray1OfInteger.hxx>
119 #include <Standard_Failure.hxx>
120 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
122 // Includes added for GetInPlace algorithm improvement
124 #include <GEOMImpl_MeasureDriver.hxx>
125 #include <GEOMImpl_IMeasure.hxx>
126 #include <BRepBuilderAPI_MakeVertex.hxx>
128 #include <BRepClass_FaceClassifier.hxx>
129 #include <BRepClass3d_SolidClassifier.hxx>
130 #include <Precision.hxx>
132 //=============================================================================
136 //=============================================================================
137 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
138 : GEOM_IOperations(theEngine, theDocID)
140 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
143 //=============================================================================
147 //=============================================================================
148 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
150 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
154 //=============================================================================
158 //=============================================================================
159 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
160 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
164 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
166 //Add a new Edge object
167 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
169 //Add a new Vector function
170 Handle(GEOM_Function) aFunction =
171 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
173 //Check if the function is set correctly
174 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
176 GEOMImpl_IVector aPI (aFunction);
178 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
179 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
180 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
182 aPI.SetPoint1(aRef1);
183 aPI.SetPoint2(aRef2);
185 //Compute the Edge value
187 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
190 if (!GetSolver()->ComputeFunction(aFunction)) {
191 SetErrorCode("Vector driver failed");
195 catch (Standard_Failure) {
196 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
197 SetErrorCode(aFail->GetMessageString());
201 //Make a Python command
202 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
203 << thePnt1 << ", " << thePnt2 << ")";
209 //=============================================================================
213 //=============================================================================
214 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
215 (list<Handle(GEOM_Object)> theShapes)
217 return MakeShape(theShapes, GEOM_WIRE, WIRE_EDGES, "MakeWire");
220 //=============================================================================
224 //=============================================================================
225 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
226 const bool isPlanarWanted)
230 if (theWire.IsNull()) return NULL;
232 //Add a new Face object
233 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
235 //Add a new Shape function for creation of a face from a wire
236 Handle(GEOM_Function) aFunction =
237 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
238 if (aFunction.IsNull()) return NULL;
240 //Check if the function is set correctly
241 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
243 GEOMImpl_IShapes aCI (aFunction);
245 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
247 if (aRefWire.IsNull()) return NULL;
249 aCI.SetBase(aRefWire);
250 aCI.SetIsPlanar(isPlanarWanted);
252 //Compute the Face value
254 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
257 if (!GetSolver()->ComputeFunction(aFunction)) {
258 SetErrorCode("Shape driver failed to compute a face");
262 catch (Standard_Failure) {
263 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
264 SetErrorCode(aFail->GetMessageString());
268 //Make a Python command
269 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
270 << theWire << ", " << (int)isPlanarWanted << ")";
276 //=============================================================================
280 //=============================================================================
281 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
282 (list<Handle(GEOM_Object)> theShapes,
283 const bool isPlanarWanted)
288 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
291 Handle(GEOM_Function) aFunction =
292 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
293 if (aFunction.IsNull()) return NULL;
295 //Check if the function is set correctly
296 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
298 GEOMImpl_IShapes aCI (aFunction);
300 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
303 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
304 for (; it != theShapes.end(); it++) {
305 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
306 if (aRefSh.IsNull()) {
307 SetErrorCode("NULL argument shape for the face construction");
310 aShapesSeq->Append(aRefSh);
312 aCI.SetShapes(aShapesSeq);
314 aCI.SetIsPlanar(isPlanarWanted);
318 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
321 if (!GetSolver()->ComputeFunction(aFunction)) {
322 SetErrorCode("Shape driver failed");
326 catch (Standard_Failure) {
327 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
328 SetErrorCode(aFail->GetMessageString());
332 //Make a Python command
333 GEOM::TPythonDump pd (aFunction);
334 pd << aShape << " = geompy.MakeFaceWires([";
337 it = theShapes.begin();
338 if (it != theShapes.end()) {
340 while (it != theShapes.end()) {
341 pd << ", " << (*it++);
344 pd << "], " << (int)isPlanarWanted << ")";
350 //=============================================================================
354 //=============================================================================
355 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
356 (list<Handle(GEOM_Object)> theShapes)
358 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
361 //=============================================================================
365 //=============================================================================
366 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
367 (list<Handle(GEOM_Object)> theShapes)
369 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
372 //=============================================================================
376 //=============================================================================
377 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
381 if (theShell.IsNull()) return NULL;
383 //Add a new Solid object
384 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
386 //Add a new Solid function for creation of a solid from a shell
387 Handle(GEOM_Function) aFunction =
388 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
389 if (aFunction.IsNull()) return NULL;
391 //Check if the function is set correctly
392 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
394 GEOMImpl_IShapes aCI (aFunction);
396 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
398 if (aRefShell.IsNull()) return NULL;
400 aCI.SetBase(aRefShell);
402 //Compute the Solid value
404 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
407 if (!GetSolver()->ComputeFunction(aFunction)) {
408 SetErrorCode("Solid driver failed");
412 catch (Standard_Failure) {
413 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
414 SetErrorCode(aFail->GetMessageString());
418 //Make a Python command
419 GEOM::TPythonDump(aFunction) << aSolid
420 << " = geompy.MakeSolid(" << theShell << ")";
426 //=============================================================================
430 //=============================================================================
431 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
432 (list<Handle(GEOM_Object)> theShapes)
434 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
437 //=============================================================================
441 //=============================================================================
442 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
443 (list<Handle(GEOM_Object)> theShapes,
444 const Standard_Integer theObjectType,
445 const Standard_Integer theFunctionType,
446 const TCollection_AsciiString& theMethodName)
451 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
454 Handle(GEOM_Function) aFunction =
455 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
456 if (aFunction.IsNull()) return NULL;
458 //Check if the function is set correctly
459 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
461 GEOMImpl_IShapes aCI (aFunction);
463 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
466 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
467 for (; it != theShapes.end(); it++) {
468 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
469 if (aRefSh.IsNull()) {
470 SetErrorCode("NULL argument shape for the shape construction");
473 aShapesSeq->Append(aRefSh);
475 aCI.SetShapes(aShapesSeq);
479 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
482 if (!GetSolver()->ComputeFunction(aFunction)) {
483 SetErrorCode("Shape driver failed");
487 catch (Standard_Failure) {
488 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
489 SetErrorCode(aFail->GetMessageString());
493 //Make a Python command
494 GEOM::TPythonDump pd (aFunction);
495 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
498 it = theShapes.begin();
499 if (it != theShapes.end()) {
501 while (it != theShapes.end()) {
502 pd << ", " << (*it++);
511 //=============================================================================
515 //=============================================================================
516 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
517 (Handle(GEOM_Object) theShape,
518 const Standard_Real theTolerance,
519 const Standard_Boolean doKeepNonSolids)
523 if (theShape.IsNull()) return NULL;
525 //Add a new Glued object
526 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
528 //Add a new Glue function
529 Handle(GEOM_Function) aFunction;
530 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
531 if (aFunction.IsNull()) return NULL;
533 //Check if the function is set correctly
534 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
536 GEOMImpl_IGlue aCI (aFunction);
538 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
539 if (aRefShape.IsNull()) return NULL;
541 aCI.SetBase(aRefShape);
542 aCI.SetTolerance(theTolerance);
543 aCI.SetKeepNonSolids(doKeepNonSolids);
545 //Compute the sub-shape value
546 Standard_Boolean isWarning = Standard_False;
548 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
551 if (!GetSolver()->ComputeFunction(aFunction)) {
552 SetErrorCode("Shape driver failed to glue faces");
556 catch (Standard_Failure) {
557 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
558 SetErrorCode(aFail->GetMessageString());
559 // to provide warning
560 if (!aFunction->GetValue().IsNull()) {
561 isWarning = Standard_True;
567 //Make a Python command
568 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
569 << theShape << ", " << theTolerance << ")";
571 // to provide warning
572 if (!isWarning) SetErrorCode(OK);
576 //=============================================================================
580 //=============================================================================
581 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
582 (Handle(GEOM_Object) theShape,
583 const Standard_Real theTolerance)
587 if (theShape.IsNull()) return NULL;
588 TopoDS_Shape aShape = theShape->GetValue();
589 if (aShape.IsNull()) return NULL;
591 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
593 Standard_Integer iErr;
595 GEOMAlgo_Gluer1 aGluer;
596 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
597 GEOMAlgo_CoupleOfShapes aCS;
598 GEOMAlgo_ListOfCoupleOfShapes aLCS;
600 //aGluer = new GEOMAlgo_Gluer1;
601 aGluer.SetShape(aShape);
602 aGluer.SetTolerance(theTolerance);
604 iErr = aGluer.ErrorStatus();
605 if (iErr) return NULL;
607 TopTools_ListOfShape listShape;
608 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
610 aItCS.Initialize(aLCSG);
611 for (; aItCS.More(); aItCS.Next()) {
612 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
613 listShape.Append(aCSG.Shape1());
616 TopTools_ListIteratorOfListOfShape itSub (listShape);
617 TCollection_AsciiString anAsciiList, anEntry;
618 TopTools_IndexedMapOfShape anIndices;
619 TopExp::MapShapes(aShape, anIndices);
620 Handle(TColStd_HArray1OfInteger) anArray;
621 Handle(GEOM_Object) anObj;
622 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
623 TopoDS_Shape aValue = itSub.Value();
624 anArray = new TColStd_HArray1OfInteger(1,1);
625 anArray->SetValue(1, anIndices.FindIndex(aValue));
626 anObj = GetEngine()->AddSubShape(theShape, anArray);
627 if (!anObj.IsNull()) {
630 // for python command
631 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
632 anAsciiList += anEntry;
637 //Make a Python command
638 if(anAsciiList.Length()>0)
639 anAsciiList.Trunc(anAsciiList.Length() - 1);
640 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
641 GEOM::TPythonDump pd (aFunction, /*append=*/true);
642 pd << "[" << anAsciiList.ToCString();
643 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
651 //=============================================================================
653 * MakeGlueFacesByList
655 //=============================================================================
656 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
657 (Handle(GEOM_Object) theShape,
658 const Standard_Real theTolerance,
659 list<Handle(GEOM_Object)> theFaces,
660 const Standard_Boolean doKeepNonSolids)
664 if (theShape.IsNull()) return NULL;
666 //Add a new Glued object
667 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
669 //Add a new Glue function
670 Handle(GEOM_Function) aFunction;
671 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
672 if (aFunction.IsNull()) return NULL;
674 //Check if the function is set correctly
675 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
677 GEOMImpl_IGlue aCI (aFunction);
679 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
680 if (aRefShape.IsNull()) return NULL;
682 aCI.SetBase(aRefShape);
683 aCI.SetTolerance(theTolerance);
684 aCI.SetKeepNonSolids(doKeepNonSolids);
686 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
687 list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
688 for (; it != theFaces.end(); it++) {
689 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
690 if (aRefSh.IsNull()) {
691 SetErrorCode("NULL argument shape for the shape construction");
694 aFaces->Append(aRefSh);
696 aCI.SetFaces(aFaces);
698 //Compute the sub-shape value
699 Standard_Boolean isWarning = Standard_False;
701 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
704 if (!GetSolver()->ComputeFunction(aFunction)) {
705 SetErrorCode("Shape driver failed to glue faces");
709 catch (Standard_Failure) {
710 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
711 SetErrorCode(aFail->GetMessageString());
712 // to provide warning
713 if (!aFunction->GetValue().IsNull()) {
714 isWarning = Standard_True;
720 //Make a Python command
722 GEOM::TPythonDump pd(aFunction);
723 pd << aGlued << " = geompy.MakeGlueFacesByList("
724 << theShape << ", " << theTolerance << ", [";
726 it = theFaces.begin();
727 if (it != theFaces.end()) {
729 while (it != theFaces.end()) {
730 pd << ", " << (*it++);
736 // to provide warning
737 if (!isWarning) SetErrorCode(OK);
743 //=============================================================================
747 //=============================================================================
748 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
749 (Handle(GEOM_Object) theShape,
750 const Standard_Integer theShapeType,
751 const Standard_Boolean isSorted)
755 if (theShape.IsNull()) return NULL;
756 TopoDS_Shape aShape = theShape->GetValue();
757 if (aShape.IsNull()) return NULL;
759 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
761 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
762 Handle(GEOM_Object) anObj;
763 TopTools_MapOfShape mapShape;
764 TopTools_ListOfShape listShape;
766 if (aShape.ShapeType() == TopAbs_COMPOUND &&
767 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
768 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
769 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
770 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
771 for (; It.More(); It.Next()) {
772 if (mapShape.Add(It.Value())) {
773 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
774 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
775 listShape.Append(It.Value());
780 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
781 for (; exp.More(); exp.Next())
782 if (mapShape.Add(exp.Current()))
783 listShape.Append(exp.Current());
786 if (listShape.IsEmpty()) {
787 //SetErrorCode("The given shape has no sub-shapes of the requested type");
788 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
793 SortShapes(listShape);
795 TopTools_IndexedMapOfShape anIndices;
796 TopExp::MapShapes(aShape, anIndices);
797 Handle(TColStd_HArray1OfInteger) anArray;
799 Standard_Integer nbAllSubShape = anIndices.Extent();
801 TopTools_ListIteratorOfListOfShape itSub (listShape);
802 TCollection_AsciiString anAsciiList, anEntry;
803 for (int index = 1; itSub.More(); itSub.Next(), ++index)
805 TopoDS_Shape aValue = itSub.Value();
806 anArray = new TColStd_HArray1OfInteger(1,1);
807 anArray->SetValue(1, anIndices.FindIndex(aValue));
809 //anObj = GetEngine()->AddSubShape(theShape, anArray);
811 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
812 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
813 if (aFunction.IsNull()) return aSeq;
815 GEOM_ISubShape aSSI (aFunction);
816 aSSI.SetMainShape(aMainShape);
817 aSSI.SetIndices(anArray);
819 // Set function value directly, as we know it.
820 // Usage of Solver here would lead to significant loss of time,
821 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
822 // on the main shape for each being calculated sub-shape separately.
823 aFunction->SetValue(aValue);
826 if (!anObj.IsNull()) {
829 // for python command
830 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
831 anAsciiList += anEntry;
836 //Make a Python command
837 anAsciiList.Trunc(anAsciiList.Length() - 1);
839 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
840 pd << "[" << anAsciiList.ToCString();
841 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
842 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
849 //=============================================================================
853 //=============================================================================
854 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
855 (Handle(GEOM_Object) theShape,
856 const Standard_Integer theShapeType,
857 const Standard_Boolean isSorted)
861 if (theShape.IsNull()) return NULL;
862 TopoDS_Shape aShape = theShape->GetValue();
863 if (aShape.IsNull()) return NULL;
865 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
866 TopTools_MapOfShape mapShape;
867 TopTools_ListOfShape listShape;
869 if (aShape.ShapeType() == TopAbs_COMPOUND &&
870 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
871 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
872 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
873 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
874 for (; It.More(); It.Next()) {
875 if (mapShape.Add(It.Value())) {
876 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
877 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
878 listShape.Append(It.Value());
883 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
884 for (; exp.More(); exp.Next())
885 if (mapShape.Add(exp.Current()))
886 listShape.Append(exp.Current());
889 if (listShape.IsEmpty()) {
890 //SetErrorCode("The given shape has no sub-shapes of the requested type");
891 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
896 SortShapes(listShape);
898 TopTools_IndexedMapOfShape anIndices;
899 TopExp::MapShapes(aShape, anIndices);
900 Handle(TColStd_HArray1OfInteger) anArray;
902 TopTools_ListIteratorOfListOfShape itSub (listShape);
903 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
904 TopoDS_Shape aValue = itSub.Value();
905 aSeq->Append(anIndices.FindIndex(aValue));
908 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
910 //Make a Python command
911 GEOM::TPythonDump pd (aFunction, /*append=*/true);
912 pd << "listSubShapeIDs = geompy.SubShapeAll";
913 pd << (isSorted ? "SortedIDs(" : "IDs(");
914 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
920 //=============================================================================
924 //=============================================================================
925 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
926 (Handle(GEOM_Object) theMainShape,
927 const Standard_Integer theID)
931 if (theMainShape.IsNull()) return NULL;
933 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
934 anArray->SetValue(1, theID);
935 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
936 if (anObj.IsNull()) {
937 SetErrorCode("Can not get a sub-shape with the given ID");
941 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
943 //Make a Python command
944 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
945 << theMainShape << ", [" << theID << "])";
951 //=============================================================================
955 //=============================================================================
956 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
957 Handle(GEOM_Object) theSubShape)
961 TopoDS_Shape aMainShape = theMainShape->GetValue();
962 TopoDS_Shape aSubShape = theSubShape->GetValue();
964 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
966 TopTools_IndexedMapOfShape anIndices;
967 TopExp::MapShapes(aMainShape, anIndices);
968 if (anIndices.Contains(aSubShape)) {
970 return anIndices.FindIndex(aSubShape);
976 //=============================================================================
980 //=============================================================================
981 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
982 Handle(GEOM_Object) theSubShape)
986 TopoDS_Shape aMainShape = theMainShape->GetValue();
987 TopoDS_Shape aSubShape = theSubShape->GetValue();
989 if (aMainShape.IsNull() || aSubShape.IsNull()) {
990 SetErrorCode("Null argument shape given");
995 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
997 TopTools_ListOfShape CL;
998 CL.Append(aMainShape);
999 TopTools_ListIteratorOfListOfShape itC;
1000 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1001 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1002 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1003 if (it.Value().IsSame(aSubShape))
1007 CL.Append(it.Value());
1012 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1013 TopTools_MapOfShape M;
1014 for (; anExp.More(); anExp.Next()) {
1015 if (M.Add(anExp.Current())) {
1016 if (anExp.Current().IsSame(aSubShape))
1023 SetErrorCode("The sub-shape does not belong to the main shape");
1027 //=============================================================================
1029 * GetShapeTypeString
1031 //=============================================================================
1032 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1036 TCollection_AsciiString aTypeName ("Null Shape");
1038 TopoDS_Shape aShape = theShape->GetValue();
1039 if (aShape.IsNull())
1042 switch (aShape.ShapeType() )
1044 case TopAbs_COMPOUND:
1045 aTypeName = "Compound";
1047 case TopAbs_COMPSOLID:
1048 aTypeName = "Compound Solid";
1051 aTypeName = "Solid";
1054 aTypeName = "Shell";
1058 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1059 if (surf.GetType() == GeomAbs_Plane)
1060 aTypeName = "Plane";
1061 else if (surf.GetType() == GeomAbs_Cylinder)
1062 aTypeName = "Cylindrical Face";
1063 else if (surf.GetType() == GeomAbs_Sphere)
1064 aTypeName = "Spherical Face";
1065 else if (surf.GetType() == GeomAbs_Torus)
1066 aTypeName = "Toroidal Face";
1067 else if (surf.GetType() == GeomAbs_Cone)
1068 aTypeName = "Conical Face";
1070 aTypeName = "GEOM::FACE";
1078 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1079 if (curv.GetType() == GeomAbs_Line) {
1080 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1081 (Abs(curv.LastParameter()) >= 1E6))
1084 aTypeName = "Edge" ;
1085 } else if (curv.GetType() == GeomAbs_Circle) {
1086 if (curv.IsClosed())
1087 aTypeName = "Circle";
1096 aTypeName = "Vertex";
1099 aTypeName = "Shape";
1102 aTypeName = "Shape of unknown type";
1109 //=============================================================================
1113 //=============================================================================
1114 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
1118 Standard_Integer nb = 0;
1120 if (theShape.IsNull()) return -1;
1121 TopoDS_Shape aShape = theShape->GetValue();
1122 if (aShape.IsNull()) return -1;
1124 TopTools_MapOfShape mapShape;
1126 TopExp_Explorer exp (aShape, TopAbs_FACE);
1127 for (; exp.More(); exp.Next())
1128 if (mapShape.Add(exp.Current()))
1135 //=============================================================================
1139 //=============================================================================
1140 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
1144 Standard_Integer nb = 0;
1146 if (theShape.IsNull()) return -1;
1147 TopoDS_Shape aShape = theShape->GetValue();
1148 if (aShape.IsNull()) return -1;
1150 TopTools_MapOfShape mapShape;
1152 TopExp_Explorer exp (aShape, TopAbs_EDGE);
1153 for (; exp.More(); exp.Next())
1154 if (mapShape.Add(exp.Current()))
1161 //=============================================================================
1165 //=============================================================================
1166 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1170 if (theShape.IsNull()) return NULL;
1172 //Add a new reversed object
1173 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1175 //Add a new Revese function
1176 Handle(GEOM_Function) aFunction;
1177 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1178 if (aFunction.IsNull()) return NULL;
1180 //Check if the function is set correctly
1181 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1183 GEOMImpl_IShapes aSI (aFunction);
1185 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1186 if (aRefShape.IsNull()) return NULL;
1188 aSI.SetBase(aRefShape);
1190 //Compute the sub-shape value
1192 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1195 if (!GetSolver()->ComputeFunction(aFunction)) {
1196 SetErrorCode("Shape driver failed to reverse shape");
1200 catch (Standard_Failure) {
1201 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1202 SetErrorCode(aFail->GetMessageString());
1206 //Make a Python command
1207 GEOM::TPythonDump(aFunction) << aReversed
1208 << " = geompy.ChangeOrientation(" << theShape << ")";
1214 //=============================================================================
1218 //=============================================================================
1219 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1220 (Handle(GEOM_Object) theShape)
1224 if (theShape.IsNull()) return NULL;
1225 TopoDS_Shape aShape = theShape->GetValue();
1226 if (aShape.IsNull()) return NULL;
1228 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1230 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1231 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1232 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1234 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1237 SetErrorCode("The given shape has no faces");
1241 TopTools_IndexedMapOfShape anIndices;
1242 TopExp::MapShapes(aShape, anIndices);
1244 Standard_Integer id;
1245 for (; ind <= nbFaces; ind++) {
1246 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1247 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1252 //The explode doesn't change object so no new function is required.
1253 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1255 //Make a Python command
1256 GEOM::TPythonDump(aFunction, /*append=*/true)
1257 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1263 //=======================================================================
1264 //function : GetSharedShapes
1266 //=======================================================================
1268 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1269 (Handle(GEOM_Object) theShape1,
1270 Handle(GEOM_Object) theShape2,
1271 const Standard_Integer theShapeType)
1275 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1277 TopoDS_Shape aShape1 = theShape1->GetValue();
1278 TopoDS_Shape aShape2 = theShape2->GetValue();
1280 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1282 TopTools_IndexedMapOfShape anIndices;
1283 TopExp::MapShapes(aShape1, anIndices);
1284 Handle(TColStd_HArray1OfInteger) anArray;
1286 TopTools_IndexedMapOfShape mapShape1;
1287 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1289 Handle(GEOM_Object) anObj;
1290 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1291 TCollection_AsciiString anAsciiList, anEntry;
1293 TopTools_MapOfShape mapShape2;
1294 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1295 for (; exp.More(); exp.Next()) {
1296 TopoDS_Shape aSS = exp.Current();
1297 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1298 anArray = new TColStd_HArray1OfInteger(1,1);
1299 anArray->SetValue(1, anIndices.FindIndex(aSS));
1300 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1301 aSeq->Append(anObj);
1303 // for python command
1304 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1305 anAsciiList += anEntry;
1310 if (aSeq->IsEmpty()) {
1311 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1315 //Make a Python command
1316 anAsciiList.Trunc(anAsciiList.Length() - 1);
1318 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1320 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1321 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1322 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1328 //=============================================================================
1332 //=============================================================================
1333 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1334 const GEOMAlgo_State theState)
1337 case GEOMAlgo_ST_IN:
1338 theDump << "geompy.GEOM.ST_IN";
1340 case GEOMAlgo_ST_OUT:
1341 theDump << "geompy.GEOM.ST_OUT";
1343 case GEOMAlgo_ST_ON:
1344 theDump << "geompy.GEOM.ST_ON";
1346 case GEOMAlgo_ST_ONIN:
1347 theDump << "geompy.GEOM.ST_ONIN";
1349 case GEOMAlgo_ST_ONOUT:
1350 theDump << "geompy.GEOM.ST_ONOUT";
1353 theDump << "geompy.GEOM.ST_UNKNOWN";
1359 //=======================================================================
1360 //function : checkTypeShapesOn
1362 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1363 * \param theShapeType - the shape type to check
1364 * \retval bool - result of the check
1366 //=======================================================================
1368 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1370 if (theShapeType != TopAbs_VERTEX &&
1371 theShapeType != TopAbs_EDGE &&
1372 theShapeType != TopAbs_FACE &&
1373 theShapeType != TopAbs_SOLID) {
1374 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1380 //=======================================================================
1381 //function : makePlane
1383 * \brief Creates Geom_Plane
1384 * \param theAx1 - shape object defining plane parameters
1385 * \retval Handle(Geom_Surface) - resulting surface
1387 //=======================================================================
1389 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1391 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1392 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1393 TopoDS_Vertex V1, V2;
1394 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1395 if (V1.IsNull() || V2.IsNull()) {
1396 SetErrorCode("Bad edge given for the plane normal vector");
1399 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1400 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1401 if (aVec.Magnitude() < Precision::Confusion()) {
1402 SetErrorCode("Vector with null magnitude given");
1405 return new Geom_Plane(aLoc, aVec);
1408 //=======================================================================
1409 //function : makeCylinder
1411 * \brief Creates Geom_CylindricalSurface
1412 * \param theAx1 - edge defining cylinder axis
1413 * \param theRadius - cylinder radius
1414 * \retval Handle(Geom_Surface) - resulting surface
1416 //=======================================================================
1418 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1419 const Standard_Real theRadius)
1421 //Axis of the cylinder
1422 if (anAxis.ShapeType() != TopAbs_EDGE) {
1423 SetErrorCode("Not an edge given for the axis");
1426 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1427 TopoDS_Vertex V1, V2;
1428 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1429 if (V1.IsNull() || V2.IsNull()) {
1430 SetErrorCode("Bad edge given for the axis");
1433 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1434 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1435 if (aVec.Magnitude() < Precision::Confusion()) {
1436 SetErrorCode("Vector with null magnitude given");
1440 gp_Ax3 anAx3 (aLoc, aVec);
1441 return new Geom_CylindricalSurface(anAx3, theRadius);
1445 //=======================================================================
1446 //function : getShapesOnBoxIDs
1448 * \brief Find IDs of subshapes complying with given status about surface
1449 * \param theBox - the box to check state of subshapes against
1450 * \param theShape - the shape to explore
1451 * \param theShapeType - type of subshape of theShape
1452 * \param theState - required state
1453 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1455 //=======================================================================
1457 Handle(TColStd_HSequenceOfInteger)
1458 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1459 const Handle(GEOM_Object)& theShape,
1460 const Standard_Integer theShapeType,
1461 GEOMAlgo_State theState)
1463 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1465 TopoDS_Shape aBox = theBox->GetValue();
1466 TopoDS_Shape aShape = theShape->GetValue();
1468 // Check presence of triangulation, build if need
1469 if (!CheckTriangulation(aShape)) {
1470 SetErrorCode("Cannot build triangulation on the shape");
1475 GEOMAlgo_FinderShapeOn2 aFinder;
1476 Standard_Real aTol = 0.0001; // default value
1478 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
1479 aClsfBox->SetBox(aBox);
1481 aFinder.SetShape(aShape);
1482 aFinder.SetTolerance(aTol);
1483 aFinder.SetClsf(aClsfBox);
1484 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1485 aFinder.SetState(theState);
1488 // Interprete results
1489 Standard_Integer iErr = aFinder.ErrorStatus();
1490 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1492 MESSAGE(" iErr : " << iErr);
1493 TCollection_AsciiString aMsg (" iErr : ");
1494 aMsg += TCollection_AsciiString(iErr);
1498 Standard_Integer iWrn = aFinder.WarningStatus();
1499 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1501 MESSAGE(" *** iWrn : " << iWrn);
1504 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1506 if (listSS.Extent() < 1) {
1507 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1508 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1512 // Fill sequence of object IDs
1513 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1515 TopTools_IndexedMapOfShape anIndices;
1516 TopExp::MapShapes(aShape, anIndices);
1518 TopTools_ListIteratorOfListOfShape itSub (listSS);
1519 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1520 int id = anIndices.FindIndex(itSub.Value());
1521 aSeqOfIDs->Append(id);
1528 //=======================================================================
1529 //function : GetShapesOnBoxIDs
1531 * \brief Find subshapes complying with given status about surface
1532 * \param theBox - the box to check state of subshapes against
1533 * \param theShape - the shape to explore
1534 * \param theShapeType - type of subshape of theShape
1535 * \param theState - required state
1536 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1538 //=======================================================================
1540 Handle(TColStd_HSequenceOfInteger)
1541 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1542 const Handle(GEOM_Object)& theShape,
1543 const Standard_Integer theShapeType,
1544 GEOMAlgo_State theState)
1546 // Find subshapes ids
1547 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1548 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1549 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1552 // The GetShapesOnBox() doesn't change object so no new function is required.
1553 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
1555 // Make a Python command
1556 GEOM::TPythonDump(aFunction)
1557 << "listShapesOnBoxIDs = geompy.GetShapesOnQuadrangleIDs("
1560 << TopAbs_ShapeEnum(theShapeType) << ", "
1567 //=======================================================================
1568 //function : GetShapesOnBox
1570 * \brief Find subshapes complying with given status about surface
1571 * \param theBox - the box to check state of subshapes against
1572 * \param theShape - the shape to explore
1573 * \param theShapeType - type of subshape of theShape
1574 * \param theState - required state
1575 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1577 //=======================================================================
1579 Handle(TColStd_HSequenceOfTransient)
1580 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
1581 const Handle(GEOM_Object)& theShape,
1582 const Standard_Integer theShapeType,
1583 GEOMAlgo_State theState)
1585 // Find subshapes ids
1586 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1587 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1588 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1591 // Find objects by indices
1592 TCollection_AsciiString anAsciiList;
1593 Handle(TColStd_HSequenceOfTransient) aSeq;
1594 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1595 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1598 // Make a Python command
1600 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1601 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1603 GEOM::TPythonDump(aFunction)
1604 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
1607 << TopAbs_ShapeEnum(theShapeType) << ", "
1615 //=======================================================================
1616 //function : getShapesOnSurfaceIDs
1618 * \brief Find IDs of subshapes complying with given status about surface
1619 * \param theSurface - the surface to check state of subshapes against
1620 * \param theShape - the shape to explore
1621 * \param theShapeType - type of subshape of theShape
1622 * \param theState - required state
1623 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1625 //=======================================================================
1627 Handle(TColStd_HSequenceOfInteger)
1628 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1629 const TopoDS_Shape& theShape,
1630 TopAbs_ShapeEnum theShapeType,
1631 GEOMAlgo_State theState)
1633 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1635 // Check presence of triangulation, build if need
1636 if (!CheckTriangulation(theShape)) {
1637 SetErrorCode("Cannot build triangulation on the shape");
1642 GEOMAlgo_FinderShapeOn1 aFinder;
1643 Standard_Real aTol = 0.0001; // default value
1645 aFinder.SetShape(theShape);
1646 aFinder.SetTolerance(aTol);
1647 aFinder.SetSurface(theSurface);
1648 aFinder.SetShapeType(theShapeType);
1649 aFinder.SetState(theState);
1651 // Sets the minimal number of inner points for the faces that do not have own
1652 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1654 aFinder.SetNbPntsMin(3);
1655 // Sets the maximal number of inner points for edges or faces.
1656 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1657 // the performance. If this value =0, all inner points will be taken into account.
1659 aFinder.SetNbPntsMax(100);
1663 // Interprete results
1664 Standard_Integer iErr = aFinder.ErrorStatus();
1665 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1667 MESSAGE(" iErr : " << iErr);
1668 TCollection_AsciiString aMsg (" iErr : ");
1669 aMsg += TCollection_AsciiString(iErr);
1673 Standard_Integer iWrn = aFinder.WarningStatus();
1674 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1676 MESSAGE(" *** iWrn : " << iWrn);
1679 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1681 if (listSS.Extent() < 1) {
1682 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1683 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1687 // Fill sequence of object IDs
1688 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1690 TopTools_IndexedMapOfShape anIndices;
1691 TopExp::MapShapes(theShape, anIndices);
1693 TopTools_ListIteratorOfListOfShape itSub (listSS);
1694 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1695 int id = anIndices.FindIndex(itSub.Value());
1696 aSeqOfIDs->Append(id);
1702 //=======================================================================
1703 //function : getObjectsShapesOn
1705 * \brief Find shape objects and their entries by their ids
1706 * \param theShapeIDs - incoming shape ids
1707 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1708 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
1710 //=======================================================================
1712 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
1713 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
1714 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
1715 TCollection_AsciiString & theShapeEntries)
1717 Handle(TColStd_HSequenceOfTransient) aSeq;
1719 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
1721 aSeq = new TColStd_HSequenceOfTransient;
1722 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1723 TCollection_AsciiString anEntry;
1724 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
1726 anArray->SetValue(1, theShapeIDs->Value( i ));
1727 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
1728 aSeq->Append( anObj );
1730 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1731 if ( i != 1 ) theShapeEntries += ",";
1732 theShapeEntries += anEntry;
1738 //=======================================================================
1739 //function : getShapesOnSurface
1741 * \brief Find subshapes complying with given status about surface
1742 * \param theSurface - the surface to check state of subshapes against
1743 * \param theShape - the shape to explore
1744 * \param theShapeType - type of subshape of theShape
1745 * \param theState - required state
1746 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1747 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1749 //=======================================================================
1751 Handle(TColStd_HSequenceOfTransient)
1752 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
1753 const Handle(GEOM_Object)& theShape,
1754 TopAbs_ShapeEnum theShapeType,
1755 GEOMAlgo_State theState,
1756 TCollection_AsciiString & theShapeEntries)
1758 // Find subshapes ids
1759 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1760 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
1761 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1764 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
1767 //=============================================================================
1771 //=============================================================================
1772 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
1773 (const Handle(GEOM_Object)& theShape,
1774 const Standard_Integer theShapeType,
1775 const Handle(GEOM_Object)& theAx1,
1776 const GEOMAlgo_State theState)
1780 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1782 TopoDS_Shape aShape = theShape->GetValue();
1783 TopoDS_Shape anAx1 = theAx1->GetValue();
1785 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1787 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1788 if ( !checkTypeShapesOn( theShapeType ))
1792 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1793 if ( aPlane.IsNull() )
1797 TCollection_AsciiString anAsciiList;
1798 Handle(TColStd_HSequenceOfTransient) aSeq;
1799 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
1800 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1803 // Make a Python command
1805 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1806 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1808 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1809 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
1810 << aShapeType << ", " << theAx1 << ", " << theState << ")";
1816 //=============================================================================
1818 * GetShapesOnPlaneWithLocation
1820 //=============================================================================
1821 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
1822 (const Handle(GEOM_Object)& theShape,
1823 const Standard_Integer theShapeType,
1824 const Handle(GEOM_Object)& theAx1,
1825 const Handle(GEOM_Object)& thePnt,
1826 const GEOMAlgo_State theState)
1830 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
1832 TopoDS_Shape aShape = theShape->GetValue();
1833 TopoDS_Shape anAx1 = theAx1->GetValue();
1834 TopoDS_Shape anPnt = thePnt->GetValue();
1836 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
1838 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1839 if ( !checkTypeShapesOn( theShapeType ))
1843 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
1844 TopoDS_Vertex V1, V2, V3;
1845 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1846 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1848 if (V1.IsNull() || V2.IsNull()) {
1849 SetErrorCode("Bad edge given for the plane normal vector");
1852 V3 = TopoDS::Vertex(anPnt);
1855 SetErrorCode("Bad vertex given for the plane location");
1858 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
1859 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
1861 if (aVec.Magnitude() < Precision::Confusion()) {
1862 SetErrorCode("Vector with null magnitude given");
1865 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
1867 if ( aPlane.IsNull() )
1871 TCollection_AsciiString anAsciiList;
1872 Handle(TColStd_HSequenceOfTransient) aSeq;
1873 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
1874 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1877 // Make a Python command
1879 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1880 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1882 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1883 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
1884 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
1890 //=============================================================================
1892 * GetShapesOnCylinder
1894 //=============================================================================
1895 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
1896 (const Handle(GEOM_Object)& theShape,
1897 const Standard_Integer theShapeType,
1898 const Handle(GEOM_Object)& theAxis,
1899 const Standard_Real theRadius,
1900 const GEOMAlgo_State theState)
1904 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1906 TopoDS_Shape aShape = theShape->GetValue();
1907 TopoDS_Shape anAxis = theAxis->GetValue();
1909 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1911 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1912 if ( !checkTypeShapesOn( aShapeType ))
1915 // Create a cylinder surface
1916 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1917 if ( aCylinder.IsNull() )
1921 TCollection_AsciiString anAsciiList;
1922 Handle(TColStd_HSequenceOfTransient) aSeq;
1923 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
1924 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1927 // Make a Python command
1929 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1930 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1932 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1933 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
1934 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
1940 //=============================================================================
1944 //=============================================================================
1945 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
1946 (const Handle(GEOM_Object)& theShape,
1947 const Standard_Integer theShapeType,
1948 const Handle(GEOM_Object)& theCenter,
1949 const Standard_Real theRadius,
1950 const GEOMAlgo_State theState)
1954 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1956 TopoDS_Shape aShape = theShape->GetValue();
1957 TopoDS_Shape aCenter = theCenter->GetValue();
1959 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1961 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1962 if ( !checkTypeShapesOn( aShapeType ))
1965 // Center of the sphere
1966 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1967 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1969 gp_Ax3 anAx3 (aLoc, gp::DZ());
1970 Handle(Geom_SphericalSurface) aSphere =
1971 new Geom_SphericalSurface(anAx3, theRadius);
1974 TCollection_AsciiString anAsciiList;
1975 Handle(TColStd_HSequenceOfTransient) aSeq;
1976 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
1977 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1980 // Make a Python command
1982 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1983 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1985 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1986 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
1987 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
1993 //=============================================================================
1995 * GetShapesOnPlaneIDs
1997 //=============================================================================
1998 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
1999 (const Handle(GEOM_Object)& theShape,
2000 const Standard_Integer theShapeType,
2001 const Handle(GEOM_Object)& theAx1,
2002 const GEOMAlgo_State theState)
2006 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2008 TopoDS_Shape aShape = theShape->GetValue();
2009 TopoDS_Shape anAx1 = theAx1->GetValue();
2011 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2013 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2014 if ( !checkTypeShapesOn( aShapeType ))
2018 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2019 if ( aPlane.IsNull() )
2023 Handle(TColStd_HSequenceOfInteger) aSeq;
2024 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2026 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2027 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2029 // Make a Python command
2030 GEOM::TPythonDump(aFunction, /*append=*/true)
2031 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
2032 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
2038 //=============================================================================
2040 * GetShapesOnPlaneWithLocationIDs
2042 //=============================================================================
2043 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
2044 (const Handle(GEOM_Object)& theShape,
2045 const Standard_Integer theShapeType,
2046 const Handle(GEOM_Object)& theAx1,
2047 const Handle(GEOM_Object)& thePnt,
2048 const GEOMAlgo_State theState)
2052 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2054 TopoDS_Shape aShape = theShape->GetValue();
2055 TopoDS_Shape anAx1 = theAx1->GetValue();
2056 TopoDS_Shape anPnt = thePnt->GetValue();
2058 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2060 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2061 if ( !checkTypeShapesOn( aShapeType ))
2065 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
2066 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2067 TopoDS_Vertex V1, V2, V3;
2068 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2069 if (V1.IsNull() || V2.IsNull()) {
2070 SetErrorCode("Bad edge given for the plane normal vector");
2073 V3 = TopoDS::Vertex(anPnt);
2075 SetErrorCode("Bad vertex given for the plane location");
2078 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2079 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2080 if (aVec.Magnitude() < Precision::Confusion()) {
2081 SetErrorCode("Vector with null magnitude given");
2085 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2086 if ( aPlane.IsNull() )
2090 Handle(TColStd_HSequenceOfInteger) aSeq;
2091 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2093 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2094 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2096 // Make a Python command
2097 GEOM::TPythonDump(aFunction, /*append=*/true)
2098 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
2099 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
2105 //=============================================================================
2107 * GetShapesOnCylinderIDs
2109 //=============================================================================
2110 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
2111 (const Handle(GEOM_Object)& theShape,
2112 const Standard_Integer theShapeType,
2113 const Handle(GEOM_Object)& theAxis,
2114 const Standard_Real theRadius,
2115 const GEOMAlgo_State theState)
2119 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2121 TopoDS_Shape aShape = theShape->GetValue();
2122 TopoDS_Shape anAxis = theAxis->GetValue();
2124 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2126 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2127 if ( !checkTypeShapesOn( aShapeType ))
2130 // Create a cylinder surface
2131 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2132 if ( aCylinder.IsNull() )
2136 Handle(TColStd_HSequenceOfInteger) aSeq;
2137 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2139 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2140 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
2142 // Make a Python command
2143 GEOM::TPythonDump(aFunction, /*append=*/true)
2144 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2145 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2146 << theRadius << ", " << theState << ")";
2152 //=============================================================================
2154 * GetShapesOnSphereIDs
2156 //=============================================================================
2157 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
2158 (const Handle(GEOM_Object)& theShape,
2159 const Standard_Integer theShapeType,
2160 const Handle(GEOM_Object)& theCenter,
2161 const Standard_Real theRadius,
2162 const GEOMAlgo_State theState)
2166 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2168 TopoDS_Shape aShape = theShape->GetValue();
2169 TopoDS_Shape aCenter = theCenter->GetValue();
2171 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2173 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2174 if ( !checkTypeShapesOn( aShapeType ))
2177 // Center of the sphere
2178 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2179 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2181 gp_Ax3 anAx3 (aLoc, gp::DZ());
2182 Handle(Geom_SphericalSurface) aSphere =
2183 new Geom_SphericalSurface(anAx3, theRadius);
2186 Handle(TColStd_HSequenceOfInteger) aSeq;
2187 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
2189 // The GetShapesOnSphere() doesn't change object so no new function is required.
2190 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
2192 // Make a Python command
2193 GEOM::TPythonDump(aFunction, /*append=*/true)
2194 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2195 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
2196 << theRadius << ", " << theState << ")";
2202 //=======================================================================
2203 //function : getShapesOnQuadrangleIDs
2205 * \brief Find IDs of subshapes complying with given status about quadrangle
2206 * \param theShape - the shape to explore
2207 * \param theShapeType - type of subshape of theShape
2208 * \param theTopLeftPoint - top left quadrangle corner
2209 * \param theTopRigthPoint - top right quadrangle corner
2210 * \param theBottomLeftPoint - bottom left quadrangle corner
2211 * \param theBottomRigthPoint - bottom right quadrangle corner
2212 * \param theState - required state
2213 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2215 //=======================================================================
2217 Handle(TColStd_HSequenceOfInteger)
2218 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2219 const Standard_Integer theShapeType,
2220 const Handle(GEOM_Object)& theTopLeftPoint,
2221 const Handle(GEOM_Object)& theTopRigthPoint,
2222 const Handle(GEOM_Object)& theBottomLeftPoint,
2223 const Handle(GEOM_Object)& theBottomRigthPoint,
2224 const GEOMAlgo_State theState)
2228 if ( theShape.IsNull() ||
2229 theTopLeftPoint.IsNull() ||
2230 theTopRigthPoint.IsNull() ||
2231 theBottomLeftPoint.IsNull() ||
2232 theBottomRigthPoint.IsNull() )
2235 TopoDS_Shape aShape = theShape->GetValue();
2236 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
2237 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
2238 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
2239 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
2241 if (aShape.IsNull() ||
2246 aTL.ShapeType() != TopAbs_VERTEX ||
2247 aTR.ShapeType() != TopAbs_VERTEX ||
2248 aBL.ShapeType() != TopAbs_VERTEX ||
2249 aBR.ShapeType() != TopAbs_VERTEX )
2252 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2253 if ( !checkTypeShapesOn( aShapeType ))
2256 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2258 // Check presence of triangulation, build if need
2259 if (!CheckTriangulation(aShape)) {
2260 SetErrorCode("Cannot build triangulation on the shape");
2265 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
2266 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
2267 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
2268 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
2270 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
2271 Standard_Real aTol = 0.0001; // default value
2273 aFinder.SetShape(aShape);
2274 aFinder.SetTolerance(aTol);
2275 //aFinder.SetSurface(theSurface);
2276 aFinder.SetShapeType(aShapeType);
2277 aFinder.SetState(theState);
2279 // Sets the minimal number of inner points for the faces that do not have own
2280 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2282 aFinder.SetNbPntsMin(3);
2283 // Sets the maximal number of inner points for edges or faces.
2284 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2285 // the performance. If this value =0, all inner points will be taken into account.
2287 aFinder.SetNbPntsMax(100);
2291 // Interprete results
2292 Standard_Integer iErr = aFinder.ErrorStatus();
2293 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2295 MESSAGE(" iErr : " << iErr);
2296 TCollection_AsciiString aMsg (" iErr : ");
2297 aMsg += TCollection_AsciiString(iErr);
2301 Standard_Integer iWrn = aFinder.WarningStatus();
2302 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2304 MESSAGE(" *** iWrn : " << iWrn);
2307 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2309 if (listSS.Extent() < 1) {
2310 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2311 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2315 // Fill sequence of object IDs
2316 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2318 TopTools_IndexedMapOfShape anIndices;
2319 TopExp::MapShapes(aShape, anIndices);
2321 TopTools_ListIteratorOfListOfShape itSub (listSS);
2322 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2323 int id = anIndices.FindIndex(itSub.Value());
2324 aSeqOfIDs->Append(id);
2329 //=======================================================================
2330 //function : GetShapesOnQuadrangle
2332 * \brief Find subshapes complying with given status about quadrangle
2333 * \param theShape - the shape to explore
2334 * \param theShapeType - type of subshape of theShape
2335 * \param theTopLeftPoint - top left quadrangle corner
2336 * \param theTopRigthPoint - top right quadrangle corner
2337 * \param theBottomLeftPoint - bottom left quadrangle corner
2338 * \param theBottomRigthPoint - bottom right quadrangle corner
2339 * \param theState - required state
2340 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2342 //=======================================================================
2344 Handle(TColStd_HSequenceOfTransient)
2345 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
2346 const Standard_Integer theShapeType,
2347 const Handle(GEOM_Object)& theTopLeftPoint,
2348 const Handle(GEOM_Object)& theTopRigthPoint,
2349 const Handle(GEOM_Object)& theBottomLeftPoint,
2350 const Handle(GEOM_Object)& theBottomRigthPoint,
2351 const GEOMAlgo_State theState)
2354 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2355 getShapesOnQuadrangleIDs( theShape,
2360 theBottomRigthPoint,
2362 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2365 // Find objects by indices
2366 TCollection_AsciiString anAsciiList;
2367 Handle(TColStd_HSequenceOfTransient) aSeq;
2368 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2369 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2372 // Make a Python command
2374 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2375 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2377 GEOM::TPythonDump(aFunction)
2378 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
2380 << TopAbs_ShapeEnum(theShapeType) << ", "
2381 << theTopLeftPoint << ", "
2382 << theTopRigthPoint << ", "
2383 << theBottomLeftPoint << ", "
2384 << theBottomRigthPoint << ", "
2391 //=======================================================================
2392 //function : GetShapesOnQuadrangleIDs
2394 * \brief Find IDs of subshapes complying with given status about quadrangle
2395 * \param theShape - the shape to explore
2396 * \param theShapeType - type of subshape of theShape
2397 * \param theTopLeftPoint - top left quadrangle corner
2398 * \param theTopRigthPoint - top right quadrangle corner
2399 * \param theBottomLeftPoint - bottom left quadrangle corner
2400 * \param theBottomRigthPoint - bottom right quadrangle corner
2401 * \param theState - required state
2402 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2404 //=======================================================================
2406 Handle(TColStd_HSequenceOfInteger)
2407 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2408 const Standard_Integer theShapeType,
2409 const Handle(GEOM_Object)& theTopLeftPoint,
2410 const Handle(GEOM_Object)& theTopRigthPoint,
2411 const Handle(GEOM_Object)& theBottomLeftPoint,
2412 const Handle(GEOM_Object)& theBottomRigthPoint,
2413 const GEOMAlgo_State theState)
2416 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2417 getShapesOnQuadrangleIDs( theShape,
2422 theBottomRigthPoint,
2424 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2427 // Make a Python command
2429 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2430 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
2431 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
2432 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
2433 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
2434 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
2436 GEOM::TPythonDump(aFunction, /*append=*/true)
2437 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
2439 << TopAbs_ShapeEnum(theShapeType) << ", "
2440 << theTopLeftPoint << ", "
2441 << theTopRigthPoint << ", "
2442 << theBottomLeftPoint << ", "
2443 << theBottomRigthPoint << ", "
2451 //=============================================================================
2455 //=============================================================================
2456 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
2457 const TopTools_IndexedMapOfShape& theWhereIndices,
2458 const TopoDS_Shape& theWhat,
2459 TColStd_ListOfInteger& theModifiedList)
2461 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
2463 if (theWhereIndices.Contains(theWhat)) {
2464 // entity was not changed by the operation
2465 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
2466 theModifiedList.Append(aWhatIndex);
2470 // try to find in history
2471 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
2473 // search in history for all argument shapes
2474 Standard_Boolean isFound = Standard_False;
2475 Standard_Boolean isGood = Standard_False;
2477 TDF_LabelSequence aLabelSeq;
2478 theWhereFunction->GetDependency(aLabelSeq);
2479 Standard_Integer nbArg = aLabelSeq.Length();
2481 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
2483 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
2485 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
2486 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
2488 TopTools_IndexedMapOfShape anArgumentIndices;
2489 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
2491 if (anArgumentIndices.Contains(theWhat)) {
2492 isFound = Standard_True;
2493 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
2495 // Find corresponding label in history
2496 TDF_Label anArgumentHistoryLabel =
2497 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
2498 if (anArgumentHistoryLabel.IsNull()) {
2499 // Lost History of operation argument. Possibly, all its entities was removed.
2500 isGood = Standard_True;
2503 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
2505 if (aWhatHistoryLabel.IsNull()) {
2506 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
2507 isGood = Standard_False;
2509 Handle(TDataStd_IntegerArray) anIntegerArray;
2510 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2511 //Error: Empty modifications history for the sought shape.
2512 isGood = Standard_False;
2515 isGood = Standard_True;
2516 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
2517 for (imod = 1; imod <= aModifLen; imod++) {
2518 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
2529 // try compound/compsolid/shell/wire element by element
2530 bool isFoundAny = false;
2531 TopTools_MapOfShape mapShape;
2533 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
2534 theWhat.ShapeType() == TopAbs_COMPSOLID) {
2535 // recursive processing of compound/compsolid
2536 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
2537 for (; anIt.More(); anIt.Next()) {
2538 if (mapShape.Add(anIt.Value())) {
2539 TopoDS_Shape curWhat = anIt.Value();
2540 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2541 if (isFoundAny) isFound = Standard_True;
2545 else if (theWhat.ShapeType() == TopAbs_SHELL) {
2546 // try to replace a shell by its faces images
2547 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
2548 for (; anExp.More(); anExp.Next()) {
2549 if (mapShape.Add(anExp.Current())) {
2550 TopoDS_Shape curWhat = anExp.Current();
2551 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2552 if (isFoundAny) isFound = Standard_True;
2556 else if (theWhat.ShapeType() == TopAbs_WIRE) {
2557 // try to replace a wire by its edges images
2558 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
2559 for (; anExp.More(); anExp.Next()) {
2560 if (mapShape.Add(anExp.Current())) {
2561 TopoDS_Shape curWhat = anExp.Current();
2562 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2563 if (isFoundAny) isFound = Standard_True;
2575 //=============================================================================
2577 * GetShapeProperties
2579 //=============================================================================
2581 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
2584 GProp_GProps SProps, VProps;
2586 TopoDS_Shape aPntShape;
2587 Standard_Real aShapeSize;
2589 BRepGProp::VolumeProperties(aShape, VProps);
2590 aCenterMass = VProps.CentreOfMass();
2591 aShapeSize = VProps.Mass();
2592 if (aShape.ShapeType() == TopAbs_FACE) {
2593 BRepGProp::SurfaceProperties(aShape, SProps);
2594 aCenterMass = SProps.CentreOfMass();
2595 aShapeSize = SProps.Mass();
2598 aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
2599 aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
2600 tab[0] = aVertex.X();
2601 tab[1] = aVertex.Y();
2602 tab[2] = aVertex.Z();
2603 tab[3] = aShapeSize;
2607 //=============================================================================
2611 //=============================================================================
2612 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
2613 Handle(GEOM_Object) theShapeWhat)
2617 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2619 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2620 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2622 if (aWhere.IsNull() || aWhat.IsNull()) {
2623 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
2627 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
2628 if (aWhereFunction.IsNull()) {
2629 SetErrorCode("Error: aWhereFunction is Null.");
2633 TopTools_IndexedMapOfShape aWhereIndices;
2634 TopExp::MapShapes(aWhere, aWhereIndices);
2636 TColStd_ListOfInteger aModifiedList;
2637 Standard_Integer aWhereIndex;
2638 Handle(TColStd_HArray1OfInteger) aModifiedArray;
2639 Handle(GEOM_Object) aResult;
2641 bool isFound = false;
2642 Standard_Integer iType = TopAbs_SOLID;
2643 Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
2644 Standard_Real tab_aWhat[4], tab_aWhere[4];
2645 Standard_Real dl_l = 1e-3;
2646 Standard_Real min_l, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
2647 gp_Pnt aPnt, aPnt_aWhat;
2648 GProp_GProps aProps;
2651 if ( aWhat.ShapeType() == TopAbs_COMPOUND ||
2652 aWhat.ShapeType() == TopAbs_SHELL ||
2653 aWhat.ShapeType() == TopAbs_COMPSOLID ) {
2654 TopExp_Explorer Exp( aWhat, TopAbs_ShapeEnum( iType ) );
2655 if ( ! Exp.More() ) iType = TopAbs_FACE;
2657 else if ( aWhat.ShapeType() == TopAbs_FACE )
2658 iType = TopAbs_FACE;
2660 TopExp_Explorer Exp_aWhat( aWhat, TopAbs_ShapeEnum( iType ) );
2661 TopExp_Explorer Exp_aWhere( aWhere, TopAbs_ShapeEnum( iType ) );
2662 TopExp_Explorer Exp_Edge( aWhere, TopAbs_EDGE );
2664 // Find the shortest edge in theShapeWhere shape
2665 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
2666 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
2667 if ( ! nbEdge ) min_l = aProps.Mass();
2668 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
2671 // Compute tolerances
2672 Tol_1D = dl_l * min_l;
2673 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
2674 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
2677 if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
2679 // Compute the ShapeWhat Mass
2680 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
2681 if ( iType == TopAbs_SOLID ) BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
2682 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
2683 aWhat_Mass += aProps.Mass();
2686 // Finding the Sub-ShapeWhere
2687 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
2688 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
2689 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
2690 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
2691 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
2693 else if ( tab_aWhat[3] - ( tab_aWhere[3] > Tol_Mass) ) {
2694 BRepClass3d_SolidClassifier SC_aWhere (Exp_aWhere.Current(), aPnt, Precision::Confusion());
2695 BRepClass3d_SolidClassifier SC_aWhat (Exp_aWhat.Current(), aPnt, Precision::Confusion());
2696 // Block construction 3D
2697 if ( SC_aWhere.State() == TopAbs_IN && SC_aWhat.State() == TopAbs_IN ) isFound = true;
2698 // Block construction 2D
2699 else if ( SC_aWhere.State() == TopAbs_ON && SC_aWhat.State() == TopAbs_ON ) isFound = true;
2702 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
2703 aModifiedList.Append(aWhereIndex);
2704 aWhere_Mass += tab_aWhere[3];
2709 if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass ) break;
2712 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
2713 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
2714 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
2715 aModifiedArray->SetValue(imod, anIterModif.Value());
2718 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
2719 if (aResult.IsNull()) {
2720 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
2724 if (aModifiedArray->Length() > 1) {
2726 aResult->SetType(GEOM_GROUP);
2728 //Set a sub shape type
2729 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
2730 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
2732 TDF_Label aFreeLabel = aResult->GetFreeLabel();
2733 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
2736 //Make a Python command
2737 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
2739 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
2740 << theShapeWhere << ", " << theShapeWhat << ")";
2746 //=======================================================================
2747 //function : GetInPlaceByHistory
2749 //=======================================================================
2750 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
2751 (Handle(GEOM_Object) theShapeWhere,
2752 Handle(GEOM_Object) theShapeWhat)
2756 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2758 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2759 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2761 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
2763 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
2764 if (aWhereFunction.IsNull()) return NULL;
2766 //Fill array of indices
2767 TopTools_IndexedMapOfShape aWhereIndices;
2768 TopExp::MapShapes(aWhere, aWhereIndices);
2771 TColStd_ListOfInteger aModifiedList;
2772 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
2774 if (!isFound || aModifiedList.Extent() < 1) {
2775 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
2779 Handle(TColStd_HArray1OfInteger) aModifiedArray =
2780 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
2781 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
2782 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
2783 aModifiedArray->SetValue(imod, anIterModif.Value());
2787 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
2788 if (aResult.IsNull()) {
2789 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
2793 if (aModifiedArray->Length() > 1) {
2795 aResult->SetType(GEOM_GROUP);
2797 //Set a sub shape type
2798 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
2799 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
2801 TDF_Label aFreeLabel = aResult->GetFreeLabel();
2802 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
2805 //Make a Python command
2806 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
2808 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
2809 << theShapeWhere << ", " << theShapeWhat << ")";
2815 //=======================================================================
2816 //function : SortShapes
2818 //=======================================================================
2819 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
2821 Standard_Integer MaxShapes = SL.Extent();
2822 TopTools_Array1OfShape aShapes (1,MaxShapes);
2823 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
2824 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
2825 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
2827 // Computing of CentreOfMass
2828 Standard_Integer Index;
2831 TopTools_ListIteratorOfListOfShape it(SL);
2832 for (Index=1; it.More(); Index++)
2834 TopoDS_Shape S = it.Value();
2835 SL.Remove( it ); // == it.Next()
2837 OrderInd.SetValue (Index, Index);
2838 if (S.ShapeType() == TopAbs_VERTEX)
2840 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
2841 Length.SetValue( Index, (Standard_Real) S.Orientation());
2845 BRepGProp::LinearProperties (S, GPr);
2846 GPoint = GPr.CentreOfMass();
2847 Length.SetValue( Index, GPr.Mass() );
2849 MidXYZ.SetValue(Index,
2850 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
2851 //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
2855 Standard_Integer aTemp;
2856 Standard_Boolean exchange, Sort = Standard_True;
2857 Standard_Real tol = Precision::Confusion();
2860 Sort = Standard_False;
2861 for (Index=1; Index < MaxShapes; Index++)
2863 Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
2864 Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
2865 if ( dMidXYZ >= tol ) {
2866 // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
2867 // << " d: " << dMidXYZ << endl;
2868 exchange = Standard_True;
2870 else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
2871 // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
2872 // << " d: " << dLength << endl;
2873 exchange = Standard_True;
2875 else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
2876 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
2878 // equal values possible on shapes such as two halves of a sphere and
2879 // a membrane inside the sphere
2881 BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
2882 if ( box1.IsVoid() ) continue;
2883 BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
2884 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
2885 if ( dSquareExtent >= tol ) {
2886 // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
2887 exchange = Standard_True;
2889 else if ( Abs(dSquareExtent) < tol ) {
2890 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
2891 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2892 val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
2893 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2894 val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
2895 exchange = val1 > val2;
2896 // cout << "box: " << val1<<" > "<<val2 << endl;
2900 exchange = Standard_False;
2904 // cout << "exchange " << Index << " & " << Index+1 << endl;
2905 aTemp = OrderInd(Index);
2906 OrderInd(Index) = OrderInd(Index+1);
2907 OrderInd(Index+1) = aTemp;
2908 Sort = Standard_True;
2913 for (Index=1; Index <= MaxShapes; Index++)
2914 SL.Append( aShapes( OrderInd(Index) ));
2917 //=======================================================================
2918 //function : CompsolidToCompound
2920 //=======================================================================
2921 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
2923 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
2924 return theCompsolid;
2927 TopoDS_Compound aCompound;
2929 B.MakeCompound(aCompound);
2931 TopTools_MapOfShape mapShape;
2932 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
2934 for (; It.More(); It.Next()) {
2935 TopoDS_Shape aShape_i = It.Value();
2936 if (mapShape.Add(aShape_i)) {
2937 B.Add(aCompound, aShape_i);
2944 //=======================================================================
2945 //function : CheckTriangulation
2947 //=======================================================================
2948 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
2950 bool isTriangulation = true;
2952 TopExp_Explorer exp (aShape, TopAbs_FACE);
2955 TopLoc_Location aTopLoc;
2956 Handle(Poly_Triangulation) aTRF;
2957 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
2958 if (aTRF.IsNull()) {
2959 isTriangulation = false;
2962 else // no faces, try edges
2964 TopExp_Explorer expe (aShape, TopAbs_EDGE);
2968 TopLoc_Location aLoc;
2969 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
2971 isTriangulation = false;
2975 if (!isTriangulation) {
2976 // calculate deflection
2977 Standard_Real aDeviationCoefficient = 0.001;
2980 BRepBndLib::Add(aShape, B);
2981 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
2982 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2984 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
2985 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
2986 Standard_Real aHLRAngle = 0.349066;
2988 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
2994 #define MAX_TOLERANCE 1.e-7
2997 //=======================================================================
2998 //function : isSameEdge
2999 //purpose : Returns True if two edges coincide
3000 //=======================================================================
3001 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
3003 TopoDS_Vertex V11, V12, V21, V22;
3004 TopExp::Vertices(theEdge1, V11, V12);
3005 TopExp::Vertices(theEdge2, V21, V22);
3006 gp_Pnt P11 = BRep_Tool::Pnt(V11);
3007 gp_Pnt P12 = BRep_Tool::Pnt(V12);
3008 gp_Pnt P21 = BRep_Tool::Pnt(V21);
3009 gp_Pnt P22 = BRep_Tool::Pnt(V22);
3010 bool coincide = false;
3012 //Check that ends of edges coincide
3013 if(P11.Distance(P21) <= MAX_TOLERANCE) {
3014 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
3016 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
3017 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
3020 if(!coincide) return false;
3022 double U11, U12, U21, U22;
3023 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
3024 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
3025 if(C1->DynamicType() == C2->DynamicType()) return true;
3027 //Check that both edges has the same geometry
3028 double range = U12-U11;
3029 double U = U11+ range/3.0;
3030 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
3031 U = U11+range*2.0/3.0;
3032 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
3034 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
3037 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3039 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
3042 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3047 #include <TopoDS_TShape.hxx>
3048 //=======================================================================
3049 //function : isSameFace
3050 //purpose : Returns True if two faces coincide
3051 //=======================================================================
3052 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
3054 TopExp_Explorer E(theFace1, TopAbs_EDGE);
3055 TopTools_ListOfShape LS1, LS2;
3056 for(; E.More(); E.Next()) LS1.Append(E.Current());
3058 E.Init(theFace2, TopAbs_EDGE);
3059 for(; E.More(); E.Next()) LS2.Append(E.Current());
3061 //Compare the number of edges in the faces
3062 if(LS1.Extent() != LS2.Extent()) return false;
3064 double aMin = RealFirst(), aMax = RealLast();
3065 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3066 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3068 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
3069 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3070 if(P.X() < xminB1) xminB1 = P.X();
3071 if(P.Y() < yminB1) yminB1 = P.Y();
3072 if(P.Z() < zminB1) zminB1 = P.Z();
3073 if(P.X() > xmaxB1) xmaxB1 = P.X();
3074 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3075 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3078 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
3079 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3080 if(P.X() < xminB2) xminB2 = P.X();
3081 if(P.Y() < yminB2) yminB2 = P.Y();
3082 if(P.Z() < zminB2) zminB2 = P.Z();
3083 if(P.X() > xmaxB2) xmaxB2 = P.X();
3084 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3085 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3089 //Compare the bounding boxes of both faces
3090 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3093 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3096 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
3097 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
3099 //Check if there a coincidence of two surfaces at least in two points
3100 double U11, U12, V11, V12, U21, U22, V21, V22;
3101 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
3102 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
3104 double rangeU = U12-U11;
3105 double rangeV = V12-V11;
3106 double U = U11 + rangeU/3.0;
3107 double V = V11 + rangeV/3.0;
3108 gp_Pnt P1 = S1->Value(U, V);
3109 U = U11+rangeU*2.0/3.0;
3110 V = V11+rangeV*2.0/3.0;
3111 gp_Pnt P2 = S1->Value(U, V);
3113 if(!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3116 if(P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
3118 if(!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3121 if(P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
3123 //Check that each edge of the Face1 has a counterpart in the Face2
3124 TopTools_MapOfOrientedShape aMap;
3125 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3126 for(; LSI1.More(); LSI1.Next()) {
3127 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
3128 bool isFound = false;
3129 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3130 for(; LSI2.More(); LSI2.Next()) {
3131 TopoDS_Shape aValue = LSI2.Value();
3132 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
3133 if(isSameEdge(E, TopoDS::Edge(aValue))) {
3139 if(!isFound) return false;
3145 //=======================================================================
3146 //function : isSameSolid
3147 //purpose : Returns True if two solids coincide
3148 //=======================================================================
3149 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
3151 TopExp_Explorer E(theSolid1, TopAbs_FACE);
3152 TopTools_ListOfShape LS1, LS2;
3153 for(; E.More(); E.Next()) LS1.Append(E.Current());
3154 E.Init(theSolid2, TopAbs_FACE);
3155 for(; E.More(); E.Next()) LS2.Append(E.Current());
3157 if(LS1.Extent() != LS2.Extent()) return false;
3159 double aMin = RealFirst(), aMax = RealLast();
3160 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3161 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3163 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
3164 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3165 if(P.X() < xminB1) xminB1 = P.X();
3166 if(P.Y() < yminB1) yminB1 = P.Y();
3167 if(P.Z() < zminB1) zminB1 = P.Z();
3168 if(P.X() > xmaxB1) xmaxB1 = P.X();
3169 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3170 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3173 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
3174 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3175 if(P.X() < xminB2) xminB2 = P.X();
3176 if(P.Y() < yminB2) yminB2 = P.Y();
3177 if(P.Z() < zminB2) zminB2 = P.Z();
3178 if(P.X() > xmaxB2) xmaxB2 = P.X();
3179 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3180 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3183 //Compare the bounding boxes of both solids
3184 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3187 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3190 //Check that each face of the Solid1 has a counterpart in the Solid2
3191 TopTools_MapOfOrientedShape aMap;
3192 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3193 for(; LSI1.More(); LSI1.Next()) {
3194 TopoDS_Face F = TopoDS::Face(LSI1.Value());
3195 bool isFound = false;
3196 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3197 for(; LSI2.More(); LSI2.Next()) {
3198 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
3199 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
3200 aMap.Add(LSI2.Value());
3205 if(!isFound) return false;
3211 //=======================================================================
3212 //function : GetSame
3214 //=======================================================================
3215 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
3216 const Handle(GEOM_Object)& theShapeWhat)
3219 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3221 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3222 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3224 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3227 bool isFound = false;
3228 TopoDS_Shape aSubShape;
3229 TopTools_MapOfShape aMap;
3231 switch(aWhat.ShapeType()) {
3232 case TopAbs_VERTEX: {
3233 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
3234 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
3235 for(; E.More(); E.Next()) {
3236 if(!aMap.Add(E.Current())) continue;
3237 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3238 if(P.Distance(P2) <= MAX_TOLERANCE) {
3240 aSubShape = E.Current();
3247 TopoDS_Face aFace = TopoDS::Face(aWhat);
3248 TopExp_Explorer E(aWhere, TopAbs_FACE);
3249 for(; E.More(); E.Next()) {
3250 if(!aMap.Add(E.Current())) continue;
3251 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
3252 aSubShape = E.Current();
3260 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
3261 TopExp_Explorer E(aWhere, TopAbs_EDGE);
3262 for(; E.More(); E.Next()) {
3263 if(!aMap.Add(E.Current())) continue;
3264 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
3265 aSubShape = E.Current();
3272 case TopAbs_SOLID: {
3273 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
3274 TopExp_Explorer E(aWhere, TopAbs_SOLID);
3275 for(; E.More(); E.Next()) {
3276 if(!aMap.Add(E.Current())) continue;
3277 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
3278 aSubShape = E.Current();
3290 TopTools_IndexedMapOfShape anIndices;
3291 TopExp::MapShapes(aWhere, anIndices);
3292 if (anIndices.Contains(aSubShape))
3293 anIndex = anIndices.FindIndex(aSubShape);
3296 if(anIndex < 0) return NULL;
3298 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3300 anArray->SetValue(1, anIndex);
3302 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
3303 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
3305 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
3306 << theShapeWhere << ", " << theShapeWhat << ")";