1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : GEOMImpl_IAdvancedOperations.cxx
23 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
26 #include <Standard_Stream.hxx>
27 #include "GEOMImpl_IBasicOperations.hxx"
28 #include "GEOMImpl_IShapesOperations.hxx"
29 #include "GEOMImpl_IBlocksOperations.hxx"
30 #include "GEOMImpl_IAdvancedOperations.hxx"
31 #include "GEOMImpl_ILocalOperations.hxx"
32 #include "GEOMImpl_Types.hxx"
33 #include <GEOMImpl_Gen.hxx>
35 #include <utilities.h>
37 #include <Utils_ExceptHandlers.hxx>
39 #include "GEOM_Function.hxx"
40 #include "GEOM_PythonDump.hxx"
42 #include <GEOMImpl_PipeTShapeDriver.hxx>
43 #include <GEOMImpl_IPipeTShape.hxx>
46 #include <TopExp_Explorer.hxx>
48 #include <TopoDS_Vertex.hxx>
49 #include <TopTools_IndexedMapOfShape.hxx>
54 #include <BRepBuilderAPI_Transform.hxx>
55 #include <BRep_Tool.hxx>
57 /*@@ insert new functions before this line @@*/
59 #include <TFunction_DriverTable.hxx>
60 #include <TFunction_Driver.hxx>
61 #include <TFunction_Logbook.hxx>
62 #include <TDF_Tool.hxx>
63 #include <Standard_Failure.hxx>
64 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
65 #define HALF_LENGTH_MAIN_PIPE "Main pipe half length" //"Tuyau principal - demi longueur"
66 #define HALF_LENGTH_INCIDENT_PIPE "Incident pipe half length" //"Tuyau incident - demi longueur"
67 #define CIRCULAR_QUARTER_PIPE "Circular quarter of pipe" //"Circulaire - quart de tuyau"
68 #define THICKNESS "Thickness" //"Epaisseur"
69 #define FLANGE "Flange" // "Collerette"
70 #define CHAMFER_OR_FILLET "Chamfer or fillet" //"Chanfrein ou Raccord"
71 #define JUNCTION_FACE_1 "Junction 1" //"Face de jonction 1"
72 #define JUNCTION_FACE_2 "Junction 2" //"Face de jonction 2"
73 #define JUNCTION_FACE_3 "Junction 3" //"Face de jonction 3"
74 //=============================================================================
78 //=============================================================================
79 GEOMImpl_IAdvancedOperations::GEOMImpl_IAdvancedOperations(GEOM_Engine* theEngine, int theDocID) :
80 GEOM_IOperations(theEngine, theDocID) {
81 MESSAGE("GEOMImpl_IAdvancedOperations::GEOMImpl_IAdvancedOperations");
84 //=============================================================================
88 //=============================================================================
89 GEOMImpl_IAdvancedOperations::~GEOMImpl_IAdvancedOperations() {
90 MESSAGE("GEOMImpl_IAdvancedOperations::~GEOMImpl_IAdvancedOperations");
93 //=============================================================================
97 //=============================================================================
98 gp_Trsf GEOMImpl_IAdvancedOperations::GetPositionTrsf(double theL1, double theL2, Handle(GEOM_Object) theP1,
99 Handle(GEOM_Object) theP2, Handle(GEOM_Object) theP3) {
100 // Old Local Coordinates System oldLCS
102 gp_Pnt P1(-theL1, 0, 0);
103 gp_Pnt P2(theL1, 0, 0);
104 gp_Pnt P3(0, 0, theL2);
106 gp_Dir oldX(gp_Vec(P1, P2));
107 gp_Dir oldZ(gp_Vec(P0, P3));
108 gp_Ax3 oldLCS(P0, oldZ, oldX);
110 // New Local Coordinates System newLCS
111 double LocX, LocY, LocZ;
112 gp_Pnt newP1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
113 gp_Pnt newP2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
114 gp_Pnt newP3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
115 LocX = (newP1.X() + newP2.X()) / 2.;
116 LocY = (newP1.Y() + newP2.Y()) / 2.;
117 LocZ = (newP1.Z() + newP2.Z()) / 2.;
118 gp_Pnt newO(LocX, LocY, LocZ);
120 gp_Dir newX(gp_Vec(newP1, newP2)); // P1P2 Vector
121 gp_Dir newZ(gp_Vec(newO, newP3)); // OP3 Vector
122 gp_Ax3 newLCS = gp_Ax3(newO, newZ, newX);
125 aTrsf.SetDisplacement(oldLCS, newLCS);
130 //=============================================================================
132 * CheckCompatiblePosition
135 //=============================================================================
136 bool GEOMImpl_IAdvancedOperations::CheckCompatiblePosition(double& theL1, double& theL2, Handle(GEOM_Object) theP1,
137 Handle(GEOM_Object) theP2, Handle(GEOM_Object) theP3, double theTolerance) {
139 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
140 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
141 gp_Pnt P3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
143 double d12 = P1.Distance(P2);
144 double d13 = P1.Distance(P3);
145 double d23 = P2.Distance(P3);
146 // double d2 = newO.Distance(P3);
147 // std::cerr << "theL1: " << theL1 << std::endl;
148 // std::cerr << "theL2: " << theL2 << std::endl;
149 // std::cerr << "d12: " << d12 << std::endl;
150 // std::cerr << "d13: " << d13 << std::endl;
151 // std::cerr << "d23: " << d23 << std::endl;
153 if (Abs(d12) <= Precision::Confusion()) {
154 SetErrorCode("Junctions points P1 and P2 are identical");
157 if (Abs(d13) <= Precision::Confusion()) {
158 SetErrorCode("Junctions points P1 and P3 are identical");
161 if (Abs(d23) <= Precision::Confusion()) {
162 SetErrorCode("Junctions points P2 and P3 are identical");
167 double newL1 = 0.5 * d12;
168 double newL2 = sqrt(pow(d13,2)-pow(newL1,2));
169 // std::cerr << "newL1: " << newL1 << std::endl;
170 // std::cerr << "newL2: " << newL2 << std::endl;
172 // theL1*(1-theTolerance) <= newL1 <= theL1*(1+theTolerance)
174 // std::cerr << "1 - theTolerance: " << 1 - theTolerance << std::endl;
176 // std::cerr << "fabs(newL1 - theL1): " << fabs(newL1 - theL1) << std::endl;
177 if (fabs(newL1 - theL1) > Precision::Approximation()) {
178 if ( (newL1 * (1 - theTolerance) -theL1 <= Precision::Approximation()) &&
179 (newL1 * (1 + theTolerance) -theL1 >= Precision::Approximation()) ) {
180 // std::cerr << "theL1 = newL1" << std::endl;
184 SetErrorCode("Dimension for main pipe (L1) is incompatible with new position");
190 // theL2*(1-theTolerance) <= newL2 <= theL2*(1+theTolerance)
192 // std::cerr << "fabs(newL2 - theL2): " << fabs(newL2 - theL2) << std::endl;
193 if (fabs(newL2 - theL2) > Precision::Approximation()) {
194 if ( (newL2 * (1 - theTolerance) -theL2 <= Precision::Approximation()) &&
195 (newL2 * (1 + theTolerance) -theL2 >= Precision::Approximation()) ) {
196 // std::cerr << "theL2 = newL2" << std::endl;
200 SetErrorCode("Dimension for incident pipe (L2) is incompatible with new position");
204 // std::cerr << "theL1: " << theL1 << std::endl;
205 // std::cerr << "theL2: " << theL2 << std::endl;
212 //=============================================================================
214 * Generate the propagation groups of a Pipe T-Shape used for hexa mesh
216 //=============================================================================
217 bool GEOMImpl_IAdvancedOperations::MakeGroups(/*std::vector<GEOM_IOperations*> theOperations, */Handle(GEOM_Object) theShape,
218 int shapeType, double theR1, double theW1, double theL1, double theR2, double theW2, double theL2,
219 Handle(TColStd_HSequenceOfTransient) theSeq, gp_Trsf aTrsf) {
222 if (theShape.IsNull()) return false;
224 TopoDS_Shape aShape = theShape->GetValue();
225 if (aShape.IsNull()) {
226 SetErrorCode("Shape is not defined");
230 gp_Trsf aTrsfInv = aTrsf.Inverted();
232 int expectedGroups = 0;
233 if (shapeType == TSHAPE_BASIC)
234 if (Abs(theR2+theW2-theR1-theW1) <= Precision::Approximation())
238 else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET)
241 double aR1Ext = theR1 + theW1;
242 double aR2Ext = theR2 + theW2;
244 /////////////////////////
245 //// Groups of Faces ////
246 /////////////////////////
248 GEOMImpl_I3DPrimOperations* a3DPrimOperations = (GEOMImpl_I3DPrimOperations*) &theOperations[0];
249 GEOMImpl_IBlocksOperations* aBlocksOperations = (GEOMImpl_IBlocksOperations*) &theOperations[2];
250 GEOMImpl_IBooleanOperations* aBooleanOperations = (GEOMImpl_IBooleanOperations*) &theOperations[3];
251 GEOMImpl_IShapesOperations* aShapesOperations = (GEOMImpl_IShapesOperations*) &theOperations[4];
252 GEOMImpl_ITransformOperations* aTransformOperations = (GEOMImpl_ITransformOperations*) &theOperations[5];*/
254 GEOMImpl_IBooleanOperations* aBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
255 GEOMImpl_IShapesOperations* aShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
256 GEOMImpl_ITransformOperations* aTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
257 GEOMImpl_IBlocksOperations* aBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
258 GEOMImpl_I3DPrimOperations* a3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
261 // Comment the following lines when GetInPlace bug is solved
263 // Workaround of GetInPlace bug
264 // Create a bounding box that fits the shape
265 Handle(GEOM_Object) aBox = a3DPrimOperations->MakeBoxDXDYDZ(2*theL1, 2*aR1Ext, aR1Ext+theL2);
266 aBox->GetLastFunction()->SetDescription("");
267 aTransformOperations->TranslateDXDYDZ(aBox, -theL1, -aR1Ext, -aR1Ext);
268 aBox->GetLastFunction()->SetDescription("");
269 // Apply transformation to box
270 BRepBuilderAPI_Transform aTransformationBox(aBox->GetValue(), aTrsf, Standard_False);
271 TopoDS_Shape aBoxShapeTrsf = aTransformationBox.Shape();
272 aBox->GetLastFunction()->SetValue(aBoxShapeTrsf);
274 // Get the shell of the box
275 Handle(GEOM_Object) aShell = Handle(GEOM_Object)::DownCast(aShapesOperations->MakeExplode(aBox, TopAbs_SHELL, true)->Value(1));
276 aBox->GetLastFunction()->SetDescription("");
277 aShell->GetLastFunction()->SetDescription("");
278 // Get the common shapes between shell and shape
279 Handle(GEOM_Object) aCommonCompound = aBooleanOperations->MakeBoolean (theShape, aShell, 1); // MakeCommon
280 aCommonCompound->GetLastFunction()->SetDescription("");
281 // Explode the faces of common shapes => 3 faces
282 Handle(TColStd_HSequenceOfTransient) aCommonFaces = aShapesOperations->MakeExplode(aCommonCompound, TopAbs_FACE, true);
283 aCommonCompound->GetLastFunction()->SetDescription("");
284 std::list<Handle(GEOM_Object)> aCompoundOfFacesList;
286 // std::cerr << "aCommonFaces->Length(): " << aCommonFaces->Length() << std::endl;
287 for (int i=0 ; i<= aCommonFaces->Length()-4 ; i+=4) {
288 std::list<Handle(GEOM_Object)> aFacesList;
289 // std::cerr << "Create compound for junction face " << i+1 << std::endl;
290 for (int j = 1 ; j <= 4 ; j++) {
291 Handle(GEOM_Object) aFace = Handle(GEOM_Object)::DownCast(aCommonFaces->Value(i+j)); // Junction faces
292 if (!aFace.IsNull()) {
293 aFace->GetLastFunction()->SetDescription("");
294 aFacesList.push_back(aFace);
297 Handle(GEOM_Object) aCompoundOfFaces = aShapesOperations->MakeCompound(aFacesList);
298 if (!aCompoundOfFaces.IsNull()) {
299 aCompoundOfFaces->GetLastFunction()->SetDescription("");
300 // Apply transformation to compound of faces
301 // BRepBuilderAPI_Transform aTransformationCompoundOfFaces(aCompoundOfFaces->GetValue(), aTrsf, Standard_False);
302 // TopoDS_Shape aTrsf_CompoundOfFacesShape = aTransformationCompoundOfFaces.Shape();
303 // aCompoundOfFaces->GetLastFunction()->SetValue(aTrsf_CompoundOfFacesShape);
304 aCompoundOfFacesList.push_back(aCompoundOfFaces);
308 // std::cerr << "aCompoundOfFacesList.size(): " << aCompoundOfFacesList.size() << std::endl;
309 if (aCompoundOfFacesList.size() == 3) {
310 Handle(GEOM_Object) aPln1 = aCompoundOfFacesList.front();
311 aCompoundOfFacesList.pop_front();
312 Handle(GEOM_Object) aPln2 = aCompoundOfFacesList.front();
313 aCompoundOfFacesList.pop_front();
314 Handle(GEOM_Object) aPln3 = aCompoundOfFacesList.front();
315 aCompoundOfFacesList.pop_front();
320 // Uncomment the following lines when GetInPlace bug is solved
322 // Handle(GEOM_Object) aP1 = aBasicOperations->MakePointXYZ(-theL1, 0, 0);
323 // Handle(GEOM_Object) aP2 = aBasicOperations->MakePointXYZ(-0, 0, theL2);
324 // Handle(GEOM_Object) aP3 = aBasicOperations->MakePointXYZ(theL1, 0, 0);
325 // aP1->GetLastFunction()->SetDescription("");
326 // aP2->GetLastFunction()->SetDescription("");
327 // aP3->GetLastFunction()->SetDescription("");
328 // Handle(GEOM_Object) aV1 = aBasicOperations->MakeVectorDXDYDZ(-1, 0, 0);
329 // Handle(GEOM_Object) aV2 = aBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
330 // Handle(GEOM_Object) aV3 = aBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
331 // aV1->GetLastFunction()->SetDescription("");
332 // aV2->GetLastFunction()->SetDescription("");
333 // aV3->GetLastFunction()->SetDescription("");
334 // Handle(GEOM_Object) aPln1 = aBasicOperations->MakePlanePntVec(aP1, aV1, 2*(theR1+theW1+theL2));
335 // Handle(GEOM_Object) aPln2 = aBasicOperations->MakePlanePntVec(aP2, aV2, 2*(theR2+theW2));
336 // Handle(GEOM_Object) aPln3 = aBasicOperations->MakePlanePntVec(aP3, aV3, 2*(theR1+theW1+theL2));
337 // aPln1->GetLastFunction()->SetDescription("");
338 // aPln2->GetLastFunction()->SetDescription("");
339 // aPln3->GetLastFunction()->SetDescription("");
341 // BRepBuilderAPI_Transform aTransformation1(aPln1->GetValue(), aTrsf, Standard_False);
342 // TopoDS_Shape aTrsf_Shape1 = aTransformation1.Shape();
343 // aPln1->GetLastFunction()->SetValue(aTrsf_Shape1);
344 // BRepBuilderAPI_Transform aTransformation2(aPln2->GetValue(), aTrsf, Standard_False);
345 // TopoDS_Shape aTrsf_Shape2 = aTransformation2.Shape();
346 // aPln2->GetLastFunction()->SetValue(aTrsf_Shape2);
347 // BRepBuilderAPI_Transform aTransformation3(aPln3->GetValue(), aTrsf, Standard_False);
348 // TopoDS_Shape aTrsf_Shape3 = aTransformation3.Shape();
349 // aPln3->GetLastFunction()->SetValue(aTrsf_Shape3);
353 Handle(GEOM_Object) junctionFaces1 = aShapesOperations->GetInPlace(theShape, aPln1);
354 if (junctionFaces1.IsNull())
355 junctionFaces1 = aShapesOperations->GetShapesOnShapeAsCompound(aPln1, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
356 if (!junctionFaces1.IsNull()) {
357 junctionFaces1->GetLastFunction()->SetDescription("");
358 junctionFaces1->SetName("JUNCTION_FACE_1");
359 theSeq->Append(junctionFaces1);
362 SetErrorCode("Junction face 1 not found");
363 // theSeq->Append(aPln1);
366 Handle(GEOM_Object) junctionFaces2 = aShapesOperations->GetInPlace(theShape, aPln2);
367 if (junctionFaces2.IsNull())
368 junctionFaces2 = aShapesOperations->GetShapesOnShapeAsCompound(aPln2, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
369 if (!junctionFaces2.IsNull()) {
370 junctionFaces2->GetLastFunction()->SetDescription("");
371 junctionFaces2->SetName("JUNCTION_FACE_2");
372 theSeq->Append(junctionFaces2);
375 SetErrorCode("Junction face 2 not found");
376 // theSeq->Append(aPln2);
379 Handle(GEOM_Object) junctionFaces3 = aShapesOperations->GetInPlace(theShape, aPln3);
380 if (junctionFaces3.IsNull())
381 junctionFaces3 = aShapesOperations->GetShapesOnShapeAsCompound(aPln3, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
382 if (!junctionFaces3.IsNull()) {
383 junctionFaces3->GetLastFunction()->SetDescription("");
384 junctionFaces3->SetName("JUNCTION_FACE_3");
385 theSeq->Append(junctionFaces3);
388 SetErrorCode("Junction face 3 not found");
389 // theSeq->Append(aPln3);
393 /////////////////////////
394 //// Groups of Edges ////
395 /////////////////////////
396 // Result of propagate
398 // Apply inverted transformation to shape
399 BRepBuilderAPI_Transform aTransformationShapeInv(theShape->GetValue(), aTrsfInv, Standard_False);
400 TopoDS_Shape aShapeTrsfInv = aTransformationShapeInv.Shape();
401 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
402 aFunction->SetValue(aShapeTrsfInv);
404 TCollection_AsciiString theDesc = aFunction->GetDescription();
405 Handle(TColStd_HSequenceOfTransient) aSeqPropagate = aBlocksOperations->Propagate(theShape);
406 if (aSeqPropagate.IsNull() || aSeqPropagate->Length() == 0) {
407 SetErrorCode("Propagation groups not found");
410 Standard_Integer nbEdges, aNbGroups = aSeqPropagate->Length();
411 // Recover previous description to get rid of Propagate dump
412 aFunction->SetDescription(theDesc);
415 // Apply transformation to shape
416 BRepBuilderAPI_Transform aTransformationShape(theShape->GetValue(), aTrsf, Standard_False);
417 TopoDS_Shape aShapeTrsf = aTransformationShape.Shape();
418 aFunction->SetValue(aShapeTrsf);
421 bool circularFoundAndAdded = false;
422 bool incidentPipeFound = false;
423 bool mainPipeFound = false;
424 bool mainPipeFoundAndAdded = false;
425 bool radialFound =false;
426 bool flangeFound = false;
427 bool flangeFoundAndAdded = false;
428 bool chamferOrFilletFound = false;
430 for (int i=1 ; i<= aNbGroups; i++) {
433 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
437 TopoDS_Shape aGroupShape = aGroup->GetValue();
439 TopTools_IndexedMapOfShape anEdgesMap;
440 TopExp::MapShapes(aGroupShape,TopAbs_EDGE, anEdgesMap);
441 nbEdges = anEdgesMap.Extent();
443 if (shapeType == TSHAPE_BASIC) {
444 if ((nbEdges == 21) || /*R1Ext = R2Ext*/(nbEdges == 17)){
446 aGroup->SetName("THICKNESS");
448 else if (nbEdges == 6) {
449 if (!circularFoundAndAdded) {
450 circularFoundAndAdded = true;
452 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
455 else if (nbEdges == 8) {
456 incidentPipeFound = true;
457 mainPipeFound = false;
461 TopExp_Explorer Ex(aGroupShape,TopAbs_VERTEX);
463 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
464 double x=aP.X(), y=aP.Y(), z=aP.Z();
467 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
468 (Abs(y) > aR2Ext + Precision::Confusion())) {
469 incidentPipeFound = false;
472 if ( z < -Precision::Confusion()) {
473 // length of main pipe
474 mainPipeFound = true;
475 if (!mainPipeFoundAndAdded) {
476 mainPipeFoundAndAdded = true;
478 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
482 else if (Abs(x) > (theL1-Precision::Confusion())) {
483 // discretisation circulaire
485 if (!circularFoundAndAdded) {
486 circularFoundAndAdded = true;
488 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
493 if (incidentPipeFound) {
495 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
497 if (!addGroup && (!incidentPipeFound &&
501 // Flange (collerette)
504 aGroup->SetName("FLANGE");
510 else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
513 aGroup->SetName("THICKNESS");
515 else if ((nbEdges == 10) || (nbEdges == 6)) {
516 if (!circularFoundAndAdded) {
518 circularFoundAndAdded = true;
519 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
522 else if (nbEdges == 8) {
523 incidentPipeFound = true;
524 mainPipeFound = false;
527 TopExp_Explorer Ex(aGroupShape,TopAbs_VERTEX);
529 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
530 double x=aP.X(), y=aP.Y(), z=aP.Z();
532 // tuy_princ_long_avant & tuy_princ_long_apres
533 bool isMain = (((z < Precision::Confusion()) || (x < Precision::Confusion())) &&
534 ((y <= aR1Ext + Precision::Confusion()) ||
535 (y <= -(aR1Ext + Precision::Confusion())) ||
536 (y <= theR1 + Precision::Confusion()) ||
537 (y == -(theR1 + Precision::Confusion()))));
541 mainPipeFound = false;
545 if (z < Precision::Confusion()) {
547 if (!flangeFoundAndAdded) {
548 flangeFoundAndAdded = true;
550 aGroup->SetName("FLANGE");
555 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
556 (Abs(y) > aR2Ext + Precision::Confusion())) {
557 incidentPipeFound = false;
563 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
565 if (incidentPipeFound) {
567 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
569 if (!addGroup && (!incidentPipeFound &&
572 !chamferOrFilletFound)) {
574 chamferOrFilletFound = true;
575 if (shapeType == TSHAPE_CHAMFER)
576 aGroup->SetName("CHAMFER");
578 aGroup->SetName("FILLET");
584 // Add group to the list
586 theSeq->Append(aGroup);
589 // Handle(GEOM_Object) aGroup;
590 // if (shapeType == TSHAPE_BASIC) {
591 // // if (aNbGroups != 11) {
592 // // SetErrorCode("Bad number of propagation groups");
595 // aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(1));
596 // aGroup->SetName("THICKNESS");
597 // theSeq->Append(aGroup);
598 // aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(2));
599 // aGroup->SetName("CIRCULAR_QUARTER_PIPE");
600 // theSeq->Append(aGroup);
601 // aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(3));
602 // aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
603 // theSeq->Append(aGroup);
604 // aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(6));
605 // aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
606 // theSeq->Append(aGroup);
607 // aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(5));
608 // aGroup->SetName("FLANGE");
609 // theSeq->Append(aGroup);
610 // } else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
611 // if (aNbGroups != 12) {
612 // SetErrorCode("Bad number of propagation groups");
615 // aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(3));
616 // aGroup->SetName("THICKNESS");
617 // theSeq->Append(aGroup);
618 // aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(1));
619 // aGroup->SetName("CIRCULAR_QUARTER_PIPE");
620 // theSeq->Append(aGroup);
621 // aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(4));
622 // aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
623 // theSeq->Append(aGroup);
624 // aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(6));
625 // aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
626 // theSeq->Append(aGroup);
627 // aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(2));
628 // aGroup->SetName("FLANGE");
629 // theSeq->Append(aGroup);
630 // aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(7));
631 // if (shapeType == TSHAPE_CHAMFER)
632 // aGroup->SetName("CHAMFER");
634 // aGroup->SetName("FILLET");
635 // theSeq->Append(aGroup);
644 bool GEOMImpl_IAdvancedOperations::MakePipeTShapePartition(/*std::vector<GEOM_IOperations*> theOperations, */Handle(GEOM_Object) theShape,
645 double theR1, double theW1, double theL1, double theR2, double theW2, double theL2, double theH, double theW, double theRF, bool isNormal) {
648 GEOMImpl_I3DPrimOperations* a3DPrimOperations = (GEOMImpl_I3DPrimOperations*) &theOperations[0];
649 GEOMImpl_IBasicOperations* aBasicOperations = (GEOMImpl_IBasicOperations*) &theOperations[1];
650 GEOMImpl_IBlocksOperations* aBlocksOperations = (GEOMImpl_IBlocksOperations*) &theOperations[2];
651 GEOMImpl_IBooleanOperations* aBooleanOperations = (GEOMImpl_IBooleanOperations*) &theOperations[3];
652 GEOMImpl_IShapesOperations* aShapesOperations = (GEOMImpl_IShapesOperations*) &theOperations[4];
653 GEOMImpl_ITransformOperations* aTransformOperations = (GEOMImpl_ITransformOperations*) &theOperations[5];*/
655 GEOMImpl_IBasicOperations* aBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
656 GEOMImpl_IBooleanOperations* aBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
657 GEOMImpl_IShapesOperations* aShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
658 GEOMImpl_ITransformOperations* aTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
659 GEOMImpl_IBlocksOperations* aBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
660 GEOMImpl_I3DPrimOperations* a3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
662 // Build tools for partition operation:
663 // 1 face and 2 planes
665 Handle(GEOM_Object) arete_intersect_int;
666 Handle(GEOM_Object) wire_t, wire_t2, face_t, face_t2;
667 Handle(GEOM_Object) chan_racc;
668 Handle(GEOM_Object) vi1, vi2;
670 Handle(GEOM_Object) Vector_Z = aBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
671 Vector_Z->GetLastFunction()->SetDescription("");
674 double aSize = 2*(theL1 + theL2);
675 double aR1Ext = theR1 + theW1;
676 double aR2Ext = theR2 + theW2;
677 double theVertCylinderRadius = aR2Ext + theW + theRF;
678 double theHoriCylinderRadius = aR1Ext + theH + theRF;
680 // Common edges on internal cylinder
681 // std::cerr << "Search for internal edges" << std::endl;
682 Handle(GEOM_Object) box_i = a3DPrimOperations->MakeBoxDXDYDZ(theR2, theR2, theR1);
683 box_i->GetLastFunction()->SetDescription("");
684 box_i = aTransformOperations->TranslateDXDYDZ(box_i, -theR2, -theR2, 0);
685 box_i->GetLastFunction()->SetDescription("");
687 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
688 TCollection_AsciiString theDesc = aFunction->GetDescription();
689 Handle(TColStd_HSequenceOfTransient) edges_i = aShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
690 // Recover previous description to get rid of Propagate dump
691 aFunction->SetDescription(theDesc);
692 // Handle(TColStd_HSequenceOfTransient) edges_i = GetCommonShapesOnCylinders(theShape, TopAbs_EDGE, theR1, theR2);
693 if (edges_i.IsNull() || edges_i->Length() == 0) {
694 // std::cerr << "Internal edges not found" << std::endl;
695 SetErrorCode("Internal edges not found");
698 // std::cerr << "Internal edges found" << std::endl;
699 for (int i=1; i<=edges_i->Length();i++) {
700 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_i->Value(i));
701 anObj->GetLastFunction()->SetDescription("");
703 arete_intersect_int = Handle(GEOM_Object)::DownCast(edges_i->Value(1));
705 // std::cerr << "Search for internal vertices" << std::endl;
706 // search for vertices located on both internal pipes
707 aFunction = theShape->GetLastFunction();
708 theDesc = aFunction->GetDescription();
709 Handle(TColStd_HSequenceOfTransient) vertices_i = aShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
710 // Recover previous description to get rid of Propagate dump
711 aFunction->SetDescription(theDesc);
712 // Handle(TColStd_HSequenceOfTransient) vertices_i = GetCommonShapesOnCylinders(theShape, TopAbs_VERTEX, theR1, theR2);
713 if (vertices_i.IsNull() || vertices_i->Length() == 0) {
714 // std::cerr << "Internal vertices not found" << std::endl;
715 SetErrorCode("Internal vertices not found");
719 for (int i = 1; i <= vertices_i->Length(); i++) {
720 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_i->Value(i));
721 v->GetLastFunction()->SetDescription("");
722 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
723 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
724 if (Abs(aP.X()) <= Precision::Confusion()) {
725 if (Abs(aP.Y()) - theR2 <= Precision::Confusion())
727 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
728 if (Abs(aP.X()) - theR1 <= Precision::Confusion())
732 // std::cerr << "Internal vertices found" << std::endl;
734 std::list<Handle(GEOM_Object)> theShapes;
737 Handle(GEOM_Object) ve1, ve2;
739 Handle(GEOM_Object) box_e = a3DPrimOperations->MakeBoxDXDYDZ(aR2Ext, aR2Ext, aR1Ext);
740 box_e->GetLastFunction()->SetDescription("");
741 box_e = aTransformOperations->TranslateDXDYDZ(box_e, -aR2Ext, -aR2Ext, 0);
742 box_e->GetLastFunction()->SetDescription("");
743 // Common edges on external cylinder
744 // std::cerr << "Search for external edges" << std::endl;
745 aFunction = theShape->GetLastFunction();
746 theDesc = aFunction->GetDescription();
747 Handle(TColStd_HSequenceOfTransient) edges_e = aShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
748 // Recover previous description to get rid of Propagate dump
749 aFunction->SetDescription(theDesc);
750 // Handle(TColStd_HSequenceOfTransient) edges_e = GetCommonShapesOnCylinders(theShape, TopAbs_EDGE, aR1Ext, aR2Ext);
751 if (edges_e.IsNull() || edges_e->Length() == 0) {
752 // std::cerr << "External edges not found" << std::endl;
753 SetErrorCode("External edges not found");
756 for (int i=1; i<=edges_e->Length();i++) {
757 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
758 anObj->GetLastFunction()->SetDescription("");
760 // std::cerr << "External edges found" << std::endl;
762 // std::cerr << "Search for external vertices" << std::endl;
763 // search for vertices located on both external pipes
764 aFunction = theShape->GetLastFunction();
765 theDesc = aFunction->GetDescription();
766 Handle(TColStd_HSequenceOfTransient) vertices_e = aShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
767 // Recover previous description to get rid of Propagate dump
768 aFunction->SetDescription(theDesc);
769 // Handle(TColStd_HSequenceOfTransient) vertices_e = GetCommonShapesOnCylinders(theShape, TopAbs_VERTEX, aR1Ext, aR2Ext);
770 if (vertices_e.IsNull() || vertices_e->Length() == 0) {
771 // std::cerr << "External vertices not found" << std::endl;
772 SetErrorCode("External vertices not found");
776 for (int i = 1; i <= vertices_e->Length(); i++) {
777 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_e->Value(i));
778 v->GetLastFunction()->SetDescription("");
779 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
780 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
781 if (Abs(aP.X()) <= Precision::Confusion()) {
782 if (Abs(aP.Y()) - theR2 > Precision::Confusion())
784 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
785 if (Abs(aP.X()) - theR2 > Precision::Confusion())
789 // std::cerr << "External vertices found" << std::endl;
790 Handle(GEOM_Object) edge_e1, edge_e2;
792 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
795 edge_e1 = aBasicOperations->MakeLineTwoPnt(ve1, vi1);
796 if (edge_e1.IsNull()) {
797 SetErrorCode("Edge 1 could not be built");
800 } catch (Standard_Failure) {
801 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
802 SetErrorCode(aFail->GetMessageString());
807 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
810 edge_e2 = aBasicOperations->MakeLineTwoPnt(ve2, vi2);
811 if (edge_e2.IsNull()) {
812 SetErrorCode("Edge 2 could not be built");
815 } catch (Standard_Failure) {
816 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
817 SetErrorCode(aFail->GetMessageString());
821 edge_e1->GetLastFunction()->SetDescription("");
822 edge_e2->GetLastFunction()->SetDescription("");
824 std::list<Handle(GEOM_Object)> edge_e_elist;
825 edge_e_elist.push_back(arete_intersect_int);
826 edge_e_elist.push_back(edge_e1);
827 edge_e_elist.push_back(Handle(GEOM_Object)::DownCast(edges_e->Value(1)));
828 edge_e_elist.push_back(edge_e2);
829 wire_t = aShapesOperations->MakeWire(edge_e_elist, 1e-7);
830 if (wire_t.IsNull()) {
831 SetErrorCode("Impossible to build wire");
834 wire_t->GetLastFunction()->SetDescription("");
835 face_t = aShapesOperations->MakeFace(wire_t, false);
836 if (face_t.IsNull()) {
837 SetErrorCode("Impossible to build face");
840 face_t->GetLastFunction()->SetDescription("");
843 Handle(GEOM_Object) P1, P2, P3, P4, P5, P6;
844 int idP1, idP2, idP3, idP4;
849 // Handle(TColStd_HSequenceOfTransient) extremVertices;
850 Handle(GEOM_Object) box_e = a3DPrimOperations->MakeBoxDXDYDZ(theVertCylinderRadius, theVertCylinderRadius, theHoriCylinderRadius);
851 box_e->GetLastFunction()->SetDescription("");
852 box_e = aTransformOperations->TranslateDXDYDZ(box_e, -theVertCylinderRadius, -theVertCylinderRadius, 0);
853 box_e->GetLastFunction()->SetDescription("");
855 aFunction = theShape->GetLastFunction();
856 theDesc = aFunction->GetDescription();
857 Handle(TColStd_HSequenceOfTransient) extremVertices = aShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
858 // Recover previous description to get rid of Propagate dump
859 aFunction->SetDescription(theDesc);
861 // extremVertices = aShapesOperations->GetShapesOnCylinder(theShape, TopAbs_VERTEX, Vector_Z, theVertCylinderRadius, GEOMAlgo_ST_ONIN);
862 if (extremVertices.IsNull() || extremVertices->Length() == 0) {
863 std::cerr << "extremVertices.IsNull() || extremVertices->Length() == 0" << std::endl;
865 SetErrorCode("Vertices on chamfer not found");
867 SetErrorCode("Vertices on fillet not found");
871 // std::cerr << "Found " << extremVertices->Length() << " vertices" << std::endl;
872 theShapes.push_back(theShape);
873 theShapes.push_back(box_e);
874 if (extremVertices->Length() != 6) {
875 // for (int i=1; i<=extremVertices->Length(); i++){
876 // theShapes.push_back(Handle(GEOM_Object)::DownCast(extremVertices->Value(i)));
878 // Handle(GEOM_Object) aCompound = aShapesOperations->MakeCompound(theShapes);
879 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
880 // theShape->GetLastFunction()->SetValue(aCompoundShape);
881 SetErrorCode("Bad number of vertices on chamfer found");
885 // std::cerr << "BEGIN of parsing list of vertices" << std::endl;
886 for (int i=1; i<=extremVertices->Length(); i++){
887 Handle(GEOM_Object) aV = Handle(GEOM_Object)::DownCast(extremVertices->Value(i));
888 aV->GetLastFunction()->SetDescription("");
889 // std::cerr << "Vertex #" << i << std::endl;
890 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aV->GetValue()));
891 // std::cerr << "aP.X() " << aP.X() << std::endl;
892 // std::cerr << "aP.Y() " << aP.Y() << std::endl;
893 // std::cerr << "aP.Z() " << aP.Z() << std::endl;
894 // if (Abs(aP.Z() - theL2) < Precision::Confusion()) {
895 // // std::cerr << "Vertex = L2 ==> OUT" << std::endl;
899 // // std::cerr << "Vertex < 0 ==> OUT" << std::endl;
903 if (Abs(aP.X()) <= Precision::Confusion()) {
904 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
906 if (aP.Z()-ZX > Precision::Confusion()) {
913 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
915 if (aP.Z() - ZY > Precision::Confusion()) {
922 // std::cerr << "END of parsing list of vertices" << std::endl;
923 // std::cerr << "LX:";
924 // for (int i=0;i<LX.size();i++)
925 // std::cerr << " " << LX.at(i);
926 // std::cerr << std::endl;
927 // std::cerr << "LY:";
928 // for (int i=0;i<LY.size();i++)
929 // std::cerr << " " << LY.at(i);
930 // std::cerr << std::endl;
931 // std::cerr << "PZX: " << PZX << std::endl;
932 // std::cerr << "PZY: " << PZY << std::endl;
943 // std::cerr << "idP1: " << idP1 << std::endl;
944 // std::cerr << "idP2: " << idP2 << std::endl;
945 // std::cerr << "idP3: " << idP3 << std::endl;
946 // std::cerr << "idP4: " << idP4 << std::endl;
948 P1 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP1));
949 P2 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP2));
950 P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
951 P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4));
953 // std::cerr << "Building edge 1 in thickness" << std::endl;
954 Handle(GEOM_Object) Cote_1 = aBasicOperations->MakeLineTwoPnt(P1, vi1);
955 if (Cote_1.IsNull()) {
956 SetErrorCode("Impossilbe to build edge in thickness");
959 Cote_1->GetLastFunction()->SetDescription("");
961 // std::cerr << "Building edge 2 in thickness" << std::endl;
962 Handle(GEOM_Object) Cote_2 = aBasicOperations->MakeLineTwoPnt(vi2, P3);
963 if (Cote_2.IsNull()) {
964 SetErrorCode("Impossilbe to build edge in thickness");
967 Cote_2->GetLastFunction()->SetDescription("");
969 // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
970 // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
971 // std::cerr << "Getting chamfer edge on main pipe" << std::endl;
972 Handle(GEOM_Object) edge_chan_princ = aBlocksOperations->GetEdge(theShape, P1, P3);
973 if (edge_chan_princ.IsNull()) {
974 SetErrorCode("Impossilbe to find edge on main pipe");
977 edge_chan_princ->GetLastFunction()->SetDescription("");
979 // std::cerr << "Getting chamfer edge on incident pipe" << std::endl;
980 Handle(GEOM_Object) edge_chan_inc = aBlocksOperations->GetEdge(theShape, P2, P4);
981 if (edge_chan_inc.IsNull()) {
982 SetErrorCode("Impossilbe to find edge on incident pipe");
985 edge_chan_inc->GetLastFunction()->SetDescription("");
987 std::list<Handle(GEOM_Object)> edgeList1;
988 edgeList1.push_back(edge_chan_princ);
989 edgeList1.push_back(Cote_1);
990 edgeList1.push_back(arete_intersect_int);
991 edgeList1.push_back(Cote_2);
993 // std::cerr << "Creating wire 1" << std::endl;
994 wire_t = aShapesOperations->MakeWire(edgeList1, 1e-7);
995 if (wire_t.IsNull()) {
996 SetErrorCode("Impossible to build wire");
999 wire_t->GetLastFunction()->SetDescription("");
1001 // std::cerr << "Creating face 1" << std::endl;
1002 face_t = aShapesOperations->MakeFace(wire_t, false);
1003 if (face_t.IsNull()) {
1004 SetErrorCode("Impossible to build face");
1007 face_t->GetLastFunction()->SetDescription("");
1008 theShapes.push_back(face_t);
1010 gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(P2->GetValue()));
1011 gp_Pnt aP5 = BRep_Tool::Pnt(TopoDS::Vertex(vi1->GetValue()));
1012 double deltaZ = aP2.Z() - aP5.Z();
1013 // std::cerr << "Creating new point from vi1 with deltaZ = " << deltaZ << std::endl;
1014 Handle(GEOM_Object) P5bis = aTransformOperations->TranslateDXDYDZCopy(vi1, 0, 0, deltaZ);
1015 if (P5bis.IsNull()) {
1016 SetErrorCode("Impossible to translate vertex");
1019 P5bis->GetLastFunction()->SetDescription("");
1021 gp_Pnt aP4 = BRep_Tool::Pnt(TopoDS::Vertex(P4->GetValue()));
1022 gp_Pnt aP6 = BRep_Tool::Pnt(TopoDS::Vertex(vi2->GetValue()));
1023 deltaZ = aP4.Z() - aP6.Z();
1024 // std::cerr << "Creating new point from vi2 with deltaZ = " << deltaZ << std::endl;
1025 Handle(GEOM_Object) P6bis = aTransformOperations->TranslateDXDYDZCopy(vi2, 0, 0, deltaZ);
1026 if (P6bis.IsNull()) {
1027 SetErrorCode("Impossible to translate vertex");
1030 P6bis->GetLastFunction()->SetDescription("");
1032 // std::cerr << "Creating new line 1 from 2 previous points" << std::endl;
1033 Handle(GEOM_Object) Cote_3 = aBasicOperations->MakeLineTwoPnt(P5bis, P2);
1034 if (Cote_3.IsNull()) {
1035 SetErrorCode("Impossilbe to build edge in thickness");
1038 Cote_3->GetLastFunction()->SetDescription("");
1040 // std::cerr << "Creating new line 2 from 2 previous points" << std::endl;
1041 Handle(GEOM_Object) Cote_4 = aBasicOperations->MakeLineTwoPnt(P6bis, P4);
1042 if (Cote_4.IsNull()) {
1043 SetErrorCode("Impossilbe to build edge in thickness");
1046 Cote_4->GetLastFunction()->SetDescription("");
1048 // std::cerr << "Creating new line 3 from 2 previous points" << std::endl;
1049 Handle(GEOM_Object) Cote_5 = aBasicOperations->MakeLineTwoPnt(P5bis, P6bis);
1050 if (Cote_4.IsNull()) {
1051 SetErrorCode("Impossilbe to build edge in thickness");
1054 Cote_5->GetLastFunction()->SetDescription("");
1056 std::list<Handle(GEOM_Object)> edgeList2;
1057 edgeList2.push_back(edge_chan_inc);
1058 edgeList2.push_back(Cote_3);
1059 edgeList2.push_back(Cote_5);
1060 edgeList2.push_back(Cote_4);
1061 // std::cerr << "Creating wire 2" << std::endl;
1062 wire_t2 = aShapesOperations->MakeWire(edgeList2, 1e-7);
1063 if (wire_t2.IsNull()) {
1064 SetErrorCode("Impossible to build wire");
1067 wire_t2->GetLastFunction()->SetDescription("");
1068 // std::cerr << "Creating face 2" << std::endl;
1069 face_t2 = aShapesOperations->MakeFace(wire_t2, false);
1070 if (face_t2.IsNull()) {
1071 SetErrorCode("Impossible to build face");
1074 face_t2->GetLastFunction()->SetDescription("");
1075 theShapes.push_back(face_t2);
1079 Handle(GEOM_Object) aP0 = aBasicOperations->MakePointXYZ(0, 0, 0);
1080 Handle(GEOM_Object) aVZ = aBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1081 Handle(GEOM_Object) aVXZ = aBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
1082 Handle(GEOM_Object) aPlnOZ = aBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
1083 Handle(GEOM_Object) aPlnOXZ = aBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
1084 aP0->GetLastFunction()->SetDescription("");
1085 aVZ->GetLastFunction()->SetDescription("");
1086 aVXZ->GetLastFunction()->SetDescription("");
1087 aPlnOZ->GetLastFunction()->SetDescription("");
1088 aPlnOXZ->GetLastFunction()->SetDescription("");
1089 theShapes.push_back(aPlnOZ);
1090 theShapes.push_back(aPlnOXZ);
1093 Handle(GEOM_Object) Part0 = aBooleanOperations->MakeHalfPartition(theShape, face_t);
1094 if (Part0.IsNull()) {
1095 std::cerr << "Impossible to build partition between TShape and 1st face" << std::endl;
1096 SetErrorCode("Impossible to build partition between TShape and 1st face");
1099 Part0->GetLastFunction()->SetDescription("");
1101 Handle(GEOM_Object) Te3 ;
1103 if (Abs(aR1Ext - aR2Ext) <= Precision::Approximation()) {
1104 std::cerr << "External radius are identical: we do not make partition with plane OXZ" << std::endl;
1105 Te3 = aBooleanOperations->MakeHalfPartition(Part0, aPlnOZ);
1108 Handle(GEOM_Object) Part1 = aBooleanOperations->MakeHalfPartition(Part0, aPlnOXZ);
1109 if (Part1.IsNull()) {
1110 std::cerr << "Impossible to build partition between TShape and plane OXZ" << std::endl;
1111 SetErrorCode("Impossible to build partition between TShape and plane OXZ");
1114 Part1->GetLastFunction()->SetDescription("");
1115 Te3 = aBooleanOperations->MakeHalfPartition(Part1, aPlnOZ);
1118 std::cerr << "Impossible to build partition between TShape and plane OZ" << std::endl;
1119 SetErrorCode("Impossible to build partition between TShape and plane OZ");
1122 Te3->GetLastFunction()->SetDescription("");
1125 if (Abs(aR1Ext - aR2Ext) <= Precision::Approximation()){ // We should never go here
1126 SetErrorCode("Impossible to build TShape");
1130 Handle(GEOM_Object) Part1 = aBooleanOperations->MakeHalfPartition(Part0, aPlnOXZ);
1131 if (Part1.IsNull()) {
1132 std::cerr << "Impossible to build partition between TShape and plane OXZ" << std::endl;
1133 SetErrorCode("Impossible to build partition between TShape and plane OXZ");
1136 Part1->GetLastFunction()->SetDescription("");
1137 Handle(GEOM_Object) Part2 = aBooleanOperations->MakeHalfPartition(Part1, aPlnOZ);
1138 if (Part2.IsNull()) {
1139 std::cerr << "Impossible to build partition between TShape and plane OZ" << std::endl;
1140 SetErrorCode("Impossible to build partition between TShape and plane OZ");
1143 Part2->GetLastFunction()->SetDescription("");
1144 Te3 = aBooleanOperations->MakeHalfPartition(Part2, face_t2);
1146 std::cerr << "Impossible to build partition between TShape and 2nd face" << std::endl;
1147 SetErrorCode("Impossible to build partition between TShape and 2nd face");
1150 Te3->GetLastFunction()->SetDescription("");
1154 // Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
1155 // Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
1156 // Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
1157 // Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
1158 // Handle(TColStd_HArray1OfInteger) theMaterials;
1159 // partitionShapes->Append(theShape);
1160 // theTools->Append(aPlnOZ);
1161 // theTools->Append(aPlnOXZ);
1162 // theTools->Append(face_t);
1164 // theTools->Append(face_t2);
1166 // Handle(GEOM_Object) Te3 = aBooleanOperations->MakePartition(partitionShapes, theTools, theKeepInside, theRemoveInside, TopAbs_SOLID, false, theMaterials, 0, false);
1167 // if (Te3.IsNull()) {
1168 // SetErrorCode("Impossible to build partition of TShape");
1169 // Handle(GEOM_Object) aCompound = aShapesOperations->MakeCompound(theShapes);
1170 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1171 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1174 // Te3->GetLastFunction()->SetDescription("");
1177 TopoDS_Shape aShape = Te3->GetValue();
1178 theShape->GetLastFunction()->SetValue(aShape);
1184 // Mirror and glue faces
1185 bool GEOMImpl_IAdvancedOperations::MakePipeTShapeMirrorAndGlue(/*std::vector<GEOM_IOperations*> theOperations, */Handle(GEOM_Object) theShape,
1186 double theR1, double theW1, double theL1, double theR2, double theW2, double theL2) {
1190 double aSize = 2*(theL1 + theL2);
1191 double aR1Ext = theR1 + theW1;
1193 GEOMImpl_IBasicOperations* aBasicOperations = (GEOMImpl_IBasicOperations*) &theOperations[1];
1194 GEOMImpl_IShapesOperations* aShapesOperations = (GEOMImpl_IShapesOperations*) &theOperations[4];
1195 GEOMImpl_ITransformOperations* aTransformOperations = (GEOMImpl_ITransformOperations*) &theOperations[5];*/
1197 GEOMImpl_IBasicOperations* aBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
1198 GEOMImpl_IShapesOperations* aShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
1199 GEOMImpl_ITransformOperations* aTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
1202 Handle(GEOM_Object) aP0 = aBasicOperations->MakePointXYZ(0, 0, 0);
1203 aP0->GetLastFunction()->SetDescription("");
1204 Handle(GEOM_Object) aVX = aBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
1205 Handle(GEOM_Object) aVY = aBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
1206 aVX->GetLastFunction()->SetDescription("");
1207 aVY->GetLastFunction()->SetDescription("");
1208 Handle(GEOM_Object) aPlane_OX = aBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
1209 Handle(GEOM_Object) aPlane_OY = aBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
1210 aPlane_OX->GetLastFunction()->SetDescription("");
1211 aPlane_OY->GetLastFunction()->SetDescription("");
1213 Handle(GEOM_Object) Te4 = aTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
1215 SetErrorCode("Impossible to build mirror of quarter TShape");
1219 // std::list<Handle(GEOM_Object)> aShapes1, aShapes2;
1220 // aShapes1.push_back(Te3);
1221 // aShapes1.push_back(Te4);
1222 // Handle(GEOM_Object) Te5 = aShapesOperations->MakeCompound(aShapes1);
1223 // if (Te4.IsNull()) {
1224 // SetErrorCode("Impossible to build compound");
1227 // Te5->GetLastFunction()->SetDescription("");
1229 Handle(GEOM_Object) Te5 = aTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
1231 SetErrorCode("Impossible to build mirror of half TShape");
1235 Handle(GEOM_Object) Te6 = aTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
1237 SetErrorCode("Impossible to build mirror of half TShape");
1241 std::list<Handle(GEOM_Object)> aShapesList;
1242 aShapesList.push_back(theShape);
1243 aShapesList.push_back(Te4);
1244 aShapesList.push_back(Te5);
1245 aShapesList.push_back(Te6);
1246 Handle(GEOM_Object) Te7 = aShapesOperations->MakeCompound(aShapesList);
1248 SetErrorCode("Impossible to build compound");
1252 Handle(GEOM_Object) Te8 = aShapesOperations->MakeGlueFaces(Te7, 1e-7, true);
1254 SetErrorCode("Impossible to glue faces of TShape");
1258 TopoDS_Shape aShape = Te8->GetValue();
1259 // TopTools_IndexedMapOfShape aMapOfShapes;
1260 // TopExp::MapShapes(aShape, aMapOfShapes);
1261 // TopExp::MapShapes(aShape, TopAbs_COMPOUND, aMapOfShapes);
1263 // std::cerr << "aMapOfShapes.Extent(): " << aMapOfShapes.Extent() << std::endl;
1264 // if (aMapOfShapes.Extent() != 1){
1265 // SetErrorCode("Result of partition is not correct");
1269 theShape->GetLastFunction()->SetValue(aShape);
1271 Te4->GetLastFunction()->SetDescription("");
1272 Te5->GetLastFunction()->SetDescription("");
1273 Te6->GetLastFunction()->SetDescription("");
1274 Te7->GetLastFunction()->SetDescription("");
1275 Te8->GetLastFunction()->SetDescription("");
1281 //=============================================================================
1284 * Create a T-shape object with specified caracteristics for the main and the
1285 * incident pipes (radius, width, half-length).
1286 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1287 * \param theR1 Internal radius of main pipe
1288 * \param theW1 Width of main pipe
1289 * \param theL1 Half-length of main pipe
1290 * \param theR2 Internal radius of incident pipe (R2 < R1)
1291 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1292 * \param theL2 Half-length of incident pipe
1293 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1294 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1296 //=============================================================================
1297 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShape(double theR1, double theW1,
1298 double theL1, double theR2, double theW2, double theL2, bool theHexMesh) {
1299 std::cerr << "GEOMImpl_IAdvancedOperations::MakePipeTShape" << std::endl;
1302 // std::cerr << "Add a new object" << std::endl;
1303 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1305 //Add a new shape function with parameters
1306 // std::cerr << "Add a new shape function with parameters" << std::endl;
1307 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1308 if (aFunction.IsNull()) return NULL;
1310 //Check if the function is set correctly
1311 // std::cerr << "Check if the function is set correctly" << std::endl;
1312 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
1314 GEOMImpl_IPipeTShape aData(aFunction);
1322 aData.SetHexMesh(theHexMesh);
1324 // std::cerr << "Compute the resulting value" << std::endl;
1325 //Compute the resulting value
1327 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1330 if (!GetSolver()->ComputeFunction(aFunction)) {
1331 // SetErrorCode("TShape driver failed");
1332 std::cerr << "TShape driver failed" << std::endl;
1335 // std::cerr << "aShape->GetName(): " << aShape->GetName() << std::endl;
1336 } catch (Standard_Failure) {
1337 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1338 SetErrorCode(aFail->GetMessageString());
1342 GEOMImpl_IBasicOperations* aBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
1343 GEOMImpl_IBooleanOperations* aBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
1344 GEOMImpl_IShapesOperations* aShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
1345 GEOMImpl_ITransformOperations* aTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
1346 GEOMImpl_IBlocksOperations* aBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
1347 GEOMImpl_I3DPrimOperations* a3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
1348 std::vector<GEOM_IOperations*> theOperations;
1349 theOperations.push_back(a3DPrimOperations);
1350 theOperations.push_back(aBasicOperations);
1351 theOperations.push_back(aBlocksOperations);
1352 theOperations.push_back(aBooleanOperations);
1353 theOperations.push_back(aShapesOperations);
1354 theOperations.push_back(aTransformOperations);
1357 // std::cerr << "Creating partition" << std::endl;
1358 if (!MakePipeTShapePartition(/*theOperations, */aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1360 // std::cerr << "Done" << std::endl;
1361 // std::cerr << "Creating mirrors and glue" << std::endl;
1362 if (!MakePipeTShapeMirrorAndGlue(/*theOperations, */aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1364 // std::cerr << "Done" << std::endl;
1367 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1368 // std::cerr << "Add shape in result list" << std::endl;
1369 aSeq->Append(aShape);
1373 * Get the groups: BEGIN
1375 if (!MakeGroups(/*theOperations, */aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, gp_Trsf())) {
1376 // SetErrorCode("Make groups failed");
1380 TCollection_AsciiString aListRes, anEntry;
1381 // Iterate over the sequence aSeq
1382 Standard_Integer aNbGroups = aSeq->Length();
1383 Standard_Integer i = 2;
1384 for (; i <= aNbGroups; i++) {
1385 Handle(Standard_Transient) anItem = aSeq->Value(i);
1386 if (anItem.IsNull()) continue;
1387 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
1388 if (aGroup.IsNull()) continue;
1389 //Make a Python command
1390 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
1391 aListRes += anEntry + ", ";
1394 aListRes.Trunc(aListRes.Length() - 2);
1396 //Make a Python command
1397 GEOM::TPythonDump(aFunction) << "[" << aShape << ", " << aListRes.ToCString() << "] = geompy.MakePipeTShape("
1398 << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", "
1399 << theHexMesh << ")";
1402 * Get the groups: END
1405 //Make a Python command
1406 GEOM::TPythonDump(aFunction) << "[" << aShape << "] = geompy.MakePipeTShape(" << theR1 << ", " << theW1 << ", "
1407 << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theHexMesh << ")";
1415 //=============================================================================
1417 * Create a T-shape object with specified caracteristics for the main and the
1418 * incident pipes (radius, width, half-length).
1419 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1420 * \param theR1 Internal radius of main pipe
1421 * \param theW1 Width of main pipe
1422 * \param theL1 Half-length of main pipe
1423 * \param theR2 Internal radius of incident pipe (R2 < R1)
1424 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1425 * \param theL2 Half-length of incident pipe
1426 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1427 * \param theP1 1st junction point of main pipe
1428 * \param theP2 2nd junction point of main pipe
1429 * \param theP3 Junction point of incident pipe
1430 * \return List of GEOM_Objects, containing the created shape and propagation groups..
1432 //=============================================================================
1433 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShapeWithPosition(double theR1,
1434 double theW1, double theL1, double theR2, double theW2, double theL2, bool theHexMesh,
1435 Handle(GEOM_Object) theP1, Handle(GEOM_Object) theP2, Handle(GEOM_Object) theP3) {
1438 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1442 //Add a new shape function with parameters
1443 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1444 if (aFunction.IsNull()) return NULL;
1446 //Check if the function is set correctly
1447 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
1449 // Check new position
1450 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
1454 GEOMImpl_IPipeTShape aData(aFunction);
1462 aData.SetHexMesh(theHexMesh);
1464 //Compute the resulting value
1466 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1469 if (!GetSolver()->ComputeFunction(aFunction)) {
1470 SetErrorCode("TShape driver failed");
1473 } catch (Standard_Failure) {
1474 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1475 SetErrorCode(aFail->GetMessageString());
1479 GEOMImpl_IBasicOperations* aBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
1480 GEOMImpl_IBooleanOperations* aBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
1481 GEOMImpl_IShapesOperations* aShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
1482 GEOMImpl_ITransformOperations* aTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
1483 GEOMImpl_IBlocksOperations* aBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
1484 GEOMImpl_I3DPrimOperations* a3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
1485 std::vector<GEOM_IOperations*> theOperations;
1486 theOperations.push_back(a3DPrimOperations);
1487 theOperations.push_back(aBasicOperations);
1488 theOperations.push_back(aBlocksOperations);
1489 theOperations.push_back(aBooleanOperations);
1490 theOperations.push_back(aShapesOperations);
1491 theOperations.push_back(aTransformOperations);
1494 std::cerr << "Creating partition" << std::endl;
1495 if (!MakePipeTShapePartition(/*theOperations, */aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1497 std::cerr << "Done" << std::endl;
1498 std::cerr << "Creating mirrors and glue" << std::endl;
1499 if (!MakePipeTShapeMirrorAndGlue(/*theOperations, */aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1501 std::cerr << "Done" << std::endl;
1504 TopoDS_Shape Te = aShape->GetValue();
1507 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
1508 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
1509 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
1510 aFunction->SetValue(aTrsf_Shape);
1511 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1512 aSeq->Append(aShape);
1516 // Get the groups: BEGIN
1518 if (!MakeGroups(/*theOperations, */aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, aTrsf)) {
1519 // SetErrorCode("Make groups failed");
1523 TCollection_AsciiString aListRes, anEntry;
1524 // Iterate over the sequence aSeq
1525 Standard_Integer aNbGroups = aSeq->Length();
1526 Standard_Integer i = 2;
1527 for (; i <= aNbGroups; i++) {
1528 Handle(Standard_Transient) anItem = aSeq->Value(i);
1529 if (anItem.IsNull()) continue;
1530 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
1531 if (aGroup.IsNull()) continue;
1532 //Make a Python command
1533 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
1534 aListRes += anEntry + ", ";
1537 aListRes.Trunc(aListRes.Length() - 2);
1539 //Make a Python command
1540 GEOM::TPythonDump(aFunction) << "[" << aShape << ", " << aListRes.ToCString() << "] = geompy.MakePipeTShape("
1541 << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", "
1542 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3 << ")";
1545 // Get the groups: END
1549 //Make a Python command
1550 GEOM::TPythonDump(aFunction) << "[" << aShape << "] = geompy.MakePipeTShape(" << theR1 << ", " << theW1 << ", "
1551 << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theHexMesh << ", " << theP1
1552 << ", " << theP2 << ", " << theP3 << ")";
1560 //=============================================================================
1562 * Create a T-shape object with specified caracteristics for the main and the
1563 * incident pipes (radius, width, half-length).
1564 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1565 * \param theR1 Internal radius of main pipe
1566 * \param theW1 Width of main pipe
1567 * \param theL1 Half-length of main pipe
1568 * \param theR2 Internal radius of incident pipe (R2 < R1)
1569 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1570 * \param theL2 Half-length of incident pipe
1571 * \param theH Height of chamfer.
1572 * \param theW Width of chamfer.
1573 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1574 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1576 //=============================================================================
1577 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShapeChamfer(double theR1, double theW1,
1578 double theL1, double theR2, double theW2, double theL2, double theH, double theW, bool theHexMesh) {
1581 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1582 //Add a new shape function with parameters
1583 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
1584 if (aFunction.IsNull()) return NULL;
1586 //Check if the function is set correctly
1587 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
1589 GEOMImpl_IPipeTShape aData(aFunction);
1599 aData.SetHexMesh(theHexMesh);
1601 //Compute the resulting value
1603 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1606 if (!GetSolver()->ComputeFunction(aFunction)) {
1607 SetErrorCode("TShape driver failed");
1610 } catch (Standard_Failure) {
1611 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1612 SetErrorCode(aFail->GetMessageString());
1616 GEOMImpl_IBasicOperations* aBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
1617 GEOMImpl_IBooleanOperations* aBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
1618 GEOMImpl_IShapesOperations* aShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
1619 GEOMImpl_ITransformOperations* aTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
1620 GEOMImpl_IBlocksOperations* aBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
1621 GEOMImpl_I3DPrimOperations* a3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
1622 GEOMImpl_ILocalOperations* aLocalOperations = new GEOMImpl_ILocalOperations(GetEngine(), GetDocID());
1623 std::vector<GEOM_IOperations*> theOperations;
1624 theOperations.push_back(a3DPrimOperations);
1625 theOperations.push_back(aBasicOperations);
1626 theOperations.push_back(aBlocksOperations);
1627 theOperations.push_back(aBooleanOperations);
1628 theOperations.push_back(aShapesOperations);
1629 theOperations.push_back(aTransformOperations);
1632 TopoDS_Shape aShapeShape = aShape->GetValue();
1633 TopTools_IndexedMapOfShape anEdgesIndices;
1634 TopExp::MapShapes(aShapeShape, anEdgesIndices);
1635 // Common edges on external cylinders
1636 Handle(GEOM_Object) box_e;
1638 box_e = a3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
1641 box_e = a3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
1643 box_e->GetLastFunction()->SetDescription("");
1644 box_e = aTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
1645 box_e->GetLastFunction()->SetDescription("");
1647 Handle(TColStd_HSequenceOfInteger) edges_e = aShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1648 box_e->GetLastFunction()->SetDescription("");
1650 if (edges_e.IsNull() || edges_e->Length() == 0) {
1651 // std::cerr << "Internal edges not found" << std::endl;
1652 SetErrorCode("External edges not found");
1655 // std::cerr << "External edges found" << std::endl;
1656 int nbEdgesInChamfer = 0;
1657 std::list<int> theEdges;
1658 for (int i=1; i<=edges_e->Length();i++) {
1659 // Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
1660 // anObj->GetLastFunction()->SetDescription("");
1661 int edgeID = edges_e->Value(i);
1662 // std::cerr << "Edge #" << edgeID << std::endl;
1663 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
1664 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
1668 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
1669 // std::cerr << "Vertex #" << iv << ": aPt.Z() - (theR1+theW1) = " << aPt.Z() - (theR1+theW1) << std::endl;
1670 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
1671 nbEdgesInChamfer ++;
1672 theEdges.push_back(edgeID);
1673 // std::cerr << "Edge #" << edgeID << " added" << std::endl;
1677 if (theHexMesh && nbEdgesInChamfer == 1)
1680 Handle(GEOM_Object) aChamfer;
1682 aChamfer = aLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
1684 catch (Standard_Failure) {
1685 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1686 SetErrorCode(aFail->GetMessageString());
1688 aChamfer = aLocalOperations->MakeChamferEdges(aShape, theH, theW, theEdges);
1690 catch (Standard_Failure) {
1691 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1692 SetErrorCode(aFail->GetMessageString());
1696 aChamfer->GetLastFunction()->SetDescription("");
1698 TopoDS_Shape aChamferShape = aChamfer->GetValue();
1699 aFunction->SetValue(aChamferShape);
1702 bool doMesh = false;
1705 std::cerr << "Creating partition" << std::endl;
1706 if (!MakePipeTShapePartition(/*theOperations, */aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false)) {
1707 std::cerr << "PipeTShape partition failed" << std::endl;
1711 std::cerr << "Done" << std::endl;
1712 std::cerr << "Creating mirrors and glue" << std::endl;
1713 if (!MakePipeTShapeMirrorAndGlue(/*theOperations, */aShape, theR1, theW1, theL1, theR2, theW2, theL2)) {
1714 std::cerr << "PipeTShape mirrors and glue failed" << std::endl;
1718 std::cerr << "Done" << std::endl;
1721 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1722 aSeq->Append(aShape);
1726 // Get the groups: BEGIN
1728 if (!MakeGroups(/*theOperations, */aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, gp_Trsf())) {
1729 //Make a Python command
1730 GEOM::TPythonDump(aFunction) << "[" << aShape << "] = geompy.MakePipeTShapeChamfer(" << theR1 << ", " << theW1
1731 << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theH << ", " << theW
1732 << ", " << theHexMesh << ")";
1736 TCollection_AsciiString aListRes, anEntry;
1737 // Iterate over the sequence aSeq
1738 Standard_Integer aNbGroups = aSeq->Length();
1739 Standard_Integer i = 2;
1740 for (; i <= aNbGroups; i++) {
1741 Handle(Standard_Transient) anItem = aSeq->Value(i);
1742 if (anItem.IsNull()) continue;
1743 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
1744 if (aGroup.IsNull()) continue;
1745 //Make a Python command
1746 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
1747 aListRes += anEntry + ", ";
1750 aListRes.Trunc(aListRes.Length() - 2);
1752 //Make a Python command
1753 GEOM::TPythonDump(aFunction) << "[" << aShape << ", " << aListRes.ToCString()
1754 << "] = geompy.MakePipeTShapeChamfer(" << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2
1755 << ", " << theW2 << ", " << theL2 << ", " << theH << ", " << theW << ", " << theHexMesh << ")";
1759 // Get the groups: END
1762 //Make a Python command
1763 GEOM::TPythonDump(aFunction) << "[" << aShape << "] = geompy.MakePipeTShapeChamfer(" << theR1 << ", " << theW1
1764 << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theH << ", " << theW
1765 << ", " << theHexMesh << ")";
1773 //=============================================================================
1775 * Create a T-shape object with specified caracteristics for the main and the
1776 * incident pipes (radius, width, half-length).
1777 * The T-shape is placed at junction points P1, P2 and P3.
1778 * \param theR1 Internal radius of main pipe
1779 * \param theW1 Width of main pipe
1780 * \param theL1 Half-length of main pipe
1781 * \param theR2 Internal radius of incident pipe (R2 < R1)
1782 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1783 * \param theL2 Half-length of incident pipe
1784 * \param theH Height of chamfer.
1785 * \param theW Width of chamfer.
1786 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1787 * \param theP1 1st junction point of main pipe
1788 * \param theP2 2nd junction point of main pipe
1789 * \param theP3 Junction point of incident pipe
1790 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1792 //=============================================================================
1793 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShapeChamferWithPosition(double theR1,
1794 double theW1, double theL1, double theR2, double theW2, double theL2, double theH, double theW,
1795 bool theHexMesh, Handle(GEOM_Object) theP1, Handle(GEOM_Object) theP2, Handle(GEOM_Object) theP3) {
1798 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1799 //Add a new shape function with parameters
1800 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
1801 if (aFunction.IsNull()) return NULL;
1803 //Check if the function is set correctly
1804 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
1806 // Check new position
1807 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
1811 GEOMImpl_IPipeTShape aData(aFunction);
1821 aData.SetHexMesh(theHexMesh);
1823 //Compute the resulting value
1825 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1828 if (!GetSolver()->ComputeFunction(aFunction)) {
1829 SetErrorCode("TShape driver failed");
1832 } catch (Standard_Failure) {
1833 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1834 SetErrorCode(aFail->GetMessageString());
1838 GEOMImpl_IBasicOperations* aBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
1839 GEOMImpl_IBooleanOperations* aBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
1840 GEOMImpl_IShapesOperations* aShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
1841 GEOMImpl_ITransformOperations* aTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
1842 GEOMImpl_IBlocksOperations* aBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
1843 GEOMImpl_I3DPrimOperations* a3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
1844 GEOMImpl_ILocalOperations* aLocalOperations = new GEOMImpl_ILocalOperations(GetEngine(), GetDocID());
1845 std::vector<GEOM_IOperations*> theOperations;
1846 theOperations.push_back(a3DPrimOperations);
1847 theOperations.push_back(aBasicOperations);
1848 theOperations.push_back(aBlocksOperations);
1849 theOperations.push_back(aBooleanOperations);
1850 theOperations.push_back(aShapesOperations);
1851 theOperations.push_back(aTransformOperations);
1854 TopoDS_Shape aShapeShape = aShape->GetValue();
1855 TopTools_IndexedMapOfShape anEdgesIndices;
1856 TopExp::MapShapes(aShapeShape, anEdgesIndices);
1857 // Common edges on external cylinders
1858 Handle(GEOM_Object) box_e;
1860 box_e = a3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
1863 box_e = a3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
1865 box_e->GetLastFunction()->SetDescription("");
1866 box_e = aTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
1867 box_e->GetLastFunction()->SetDescription("");
1869 Handle(TColStd_HSequenceOfInteger) edges_e = aShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1870 box_e->GetLastFunction()->SetDescription("");
1872 if (edges_e.IsNull() || edges_e->Length() == 0) {
1873 // std::cerr << "Internal edges not found" << std::endl;
1874 SetErrorCode("External edges not found");
1877 // std::cerr << "External edges found" << std::endl;
1878 int nbEdgesInChamfer = 0;
1879 std::list<int> theEdges;
1880 for (int i=1; i<=edges_e->Length();i++) {
1881 // Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
1882 // anObj->GetLastFunction()->SetDescription("");
1883 int edgeID = edges_e->Value(i);
1884 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
1885 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
1887 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
1888 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
1889 nbEdgesInChamfer ++;
1890 theEdges.push_back(edgeID);
1894 if (theHexMesh && nbEdgesInChamfer == 1)
1897 Handle(GEOM_Object) aChamfer;
1899 aChamfer = aLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
1902 aChamfer = aLocalOperations->MakeChamferEdges(aShape, theH, theW, theEdges);
1904 aChamfer->GetLastFunction()->SetDescription("");
1906 TopoDS_Shape aChamferShape = aChamfer->GetValue();
1907 aFunction->SetValue(aChamferShape);
1911 std::cerr << "Creating partition" << std::endl;
1912 if (!MakePipeTShapePartition(/*theOperations, */aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
1914 std::cerr << "Done" << std::endl;
1915 std::cerr << "Creating mirrors and glue" << std::endl;
1916 if (!MakePipeTShapeMirrorAndGlue(/*theOperations, */aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1918 std::cerr << "Done" << std::endl;
1921 TopoDS_Shape Te = aShape->GetValue();
1924 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
1925 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
1926 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
1927 aFunction->SetValue(aTrsf_Shape);
1928 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1929 aSeq->Append(aShape);
1932 * Get the groups: BEGIN
1934 if (!MakeGroups(/*theOperations, */aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, aTrsf))
1937 TCollection_AsciiString aListRes, anEntry;
1938 // Iterate over the sequence aSeq
1939 Standard_Integer aNbGroups = aSeq->Length();
1940 Standard_Integer i = 2;
1941 for (; i <= aNbGroups; i++) {
1942 Handle(Standard_Transient) anItem = aSeq->Value(i);
1943 if (anItem.IsNull()) continue;
1944 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
1945 if (aGroup.IsNull()) continue;
1946 //Make a Python command
1947 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
1948 aListRes += anEntry + ", ";
1951 aListRes.Trunc(aListRes.Length() - 2);
1953 //Make a Python command
1954 GEOM::TPythonDump(aFunction) << "[" << aShape << ", " << aListRes.ToCString()
1955 << "] = geompy.MakePipeTShapeChamfer(" << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2
1956 << ", " << theW2 << ", " << theL2 << ", " << theH << ", " << theW << ", " << theHexMesh << ", "
1957 << theP1 << ", " << theP2 << ", " << theP3 << ")";
1960 * Get the groups: END
1963 //Make a Python command
1964 GEOM::TPythonDump(aFunction) << "[" << aShape << "] = geompy.MakePipeTShapeChamfer(" << theR1 << ", " << theW1
1965 << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theH << ", " << theW
1966 << ", " << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3 << ")";
1974 //=============================================================================
1976 * Create a T-shape object with specified caracteristics for the main and the
1977 * incident pipes (radius, width, half-length).A fillet is created on
1978 * the junction of the pipes.
1979 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1980 * \param theR1 Internal radius of main pipe
1981 * \param theW1 Width of main pipe
1982 * \param theL1 Half-length of main pipe
1983 * \param theR2 Internal radius of incident pipe (R2 < R1)
1984 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1985 * \param theL2 Half-length of incident pipe
1986 * \param theRF Radius of curvature of fillet.
1987 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1988 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1990 //=============================================================================
1991 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShapeFillet(double theR1, double theW1,
1992 double theL1, double theR2, double theW2, double theL2, double theRF, bool theHexMesh) {
1995 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1996 //Add a new shape function with parameters
1997 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
1998 if (aFunction.IsNull()) return NULL;
2000 //Check if the function is set correctly
2001 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2003 GEOMImpl_IPipeTShape aData(aFunction);
2012 aData.SetHexMesh(theHexMesh);
2014 //Compute the resulting value
2016 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
2019 if (!GetSolver()->ComputeFunction(aFunction)) {
2020 SetErrorCode("TShape driver failed");
2023 } catch (Standard_Failure) {
2024 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2025 SetErrorCode(aFail->GetMessageString());
2029 GEOMImpl_IBasicOperations* aBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
2030 GEOMImpl_IBooleanOperations* aBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
2031 GEOMImpl_IShapesOperations* aShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
2032 GEOMImpl_ITransformOperations* aTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
2033 GEOMImpl_IBlocksOperations* aBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
2034 GEOMImpl_I3DPrimOperations* a3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
2035 GEOMImpl_ILocalOperations* aLocalOperations = new GEOMImpl_ILocalOperations(GetEngine(), GetDocID());
2036 std::vector<GEOM_IOperations*> theOperations;
2037 theOperations.push_back(a3DPrimOperations);
2038 theOperations.push_back(aBasicOperations);
2039 theOperations.push_back(aBlocksOperations);
2040 theOperations.push_back(aBooleanOperations);
2041 theOperations.push_back(aShapesOperations);
2042 theOperations.push_back(aTransformOperations);
2045 TopoDS_Shape aShapeShape = aShape->GetValue();
2046 TopTools_IndexedMapOfShape anEdgesIndices;
2047 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2048 // Common edges on external cylinders
2049 Handle(GEOM_Object) box_e;
2051 box_e = a3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2054 box_e = a3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2056 box_e->GetLastFunction()->SetDescription("");
2057 box_e = aTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2058 box_e->GetLastFunction()->SetDescription("");
2060 Handle(TColStd_HSequenceOfInteger) edges_e = aShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2061 box_e->GetLastFunction()->SetDescription("");
2063 if (edges_e.IsNull() || edges_e->Length() == 0) {
2064 // std::cerr << "Internal edges not found" << std::endl;
2065 SetErrorCode("External edges not found");
2068 // std::cerr << "External edges found" << std::endl;
2069 int nbEdgesInFillet = 0;
2070 std::list<int> theEdges;
2071 for (int i=1; i<=edges_e->Length();i++) {
2072 // Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
2073 // anObj->GetLastFunction()->SetDescription("");
2074 int edgeID = edges_e->Value(i);
2075 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2076 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2078 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2079 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2081 theEdges.push_back(edgeID);
2085 if (theHexMesh && nbEdgesInFillet == 1)
2089 Handle(GEOM_Object) aFillet = aLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2090 aFillet->GetLastFunction()->SetDescription("");
2092 TopoDS_Shape aFilletShape = aFillet->GetValue();
2093 aFunction->SetValue(aFilletShape);
2097 std::cerr << "Creating partition" << std::endl;
2098 if (!MakePipeTShapePartition(/*theOperations, */aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2100 std::cerr << "Done" << std::endl;
2101 std::cerr << "Creating mirrors and glue" << std::endl;
2102 if (!MakePipeTShapeMirrorAndGlue(/*theOperations, */aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2104 std::cerr << "Done" << std::endl;
2107 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2108 aSeq->Append(aShape);
2111 * Get the groups: BEGIN
2113 if (!MakeGroups(/*theOperations, */aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, gp_Trsf()))
2116 TCollection_AsciiString aListRes, anEntry;
2117 // Iterate over the sequence aSeq
2118 Standard_Integer aNbGroups = aSeq->Length();
2119 Standard_Integer i = 2;
2120 for (; i <= aNbGroups; i++) {
2121 Handle(Standard_Transient) anItem = aSeq->Value(i);
2122 if (anItem.IsNull()) continue;
2123 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2124 if (aGroup.IsNull()) continue;
2125 //Make a Python command
2126 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2127 aListRes += anEntry + ", ";
2130 aListRes.Trunc(aListRes.Length() - 2);
2132 //Make a Python command
2133 GEOM::TPythonDump(aFunction) << "[" << aShape << ", " << aListRes.ToCString()
2134 << "] = geompy.MakePipeTShapeFillet(" << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2
2135 << ", " << theW2 << ", " << theL2 << ", " << theRF << ", " << theHexMesh << ")";
2138 * Get the groups: END
2141 //Make a Python command
2142 GEOM::TPythonDump(aFunction) << "[" << aShape << "] = geompy.MakePipeTShapeFillet(" << theR1 << ", " << theW1
2143 << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theRF << ", "
2144 << theHexMesh << ")";
2154 //=============================================================================
2156 * Create a T-shape object with specified caracteristics for the main and the
2157 * incident pipes (radius, width, half-length). A fillet is created on
2158 * the junction of the pipes.
2159 * The T-shape is placed at junction points P1, P2 and P3.
2160 * \param theR1 Internal radius of main pipe
2161 * \param theW1 Width of main pipe
2162 * \param theL1 Half-length of main pipe
2163 * \param theR2 Internal radius of incident pipe (R2 < R1)
2164 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2165 * \param theL2 Half-length of incident pipe
2166 * \param theRF Radius of curvature of fillet
2167 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2168 * \param theP1 1st junction point of main pipe
2169 * \param theP2 2nd junction point of main pipe
2170 * \param theP3 Junction point of incident pipe
2171 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2173 //=============================================================================
2174 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IAdvancedOperations::MakePipeTShapeFilletWithPosition(double theR1,
2175 double theW1, double theL1, double theR2, double theW2, double theL2, double theRF, bool theHexMesh,
2176 Handle(GEOM_Object) theP1, Handle(GEOM_Object) theP2, Handle(GEOM_Object) theP3) {
2179 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2180 //Add a new shape function with parameters
2181 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2182 if (aFunction.IsNull()) return NULL;
2184 //Check if the function is set correctly
2185 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2187 // Check new position
2188 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2192 GEOMImpl_IPipeTShape aData(aFunction);
2201 aData.SetHexMesh(theHexMesh);
2203 //Compute the resulting value
2205 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
2208 if (!GetSolver()->ComputeFunction(aFunction)) {
2209 SetErrorCode("TShape driver failed");
2212 } catch (Standard_Failure) {
2213 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2214 SetErrorCode(aFail->GetMessageString());
2218 GEOMImpl_IBasicOperations* aBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
2219 GEOMImpl_IBooleanOperations* aBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
2220 GEOMImpl_IShapesOperations* aShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
2221 GEOMImpl_ITransformOperations* aTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
2222 GEOMImpl_IBlocksOperations* aBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
2223 GEOMImpl_I3DPrimOperations* a3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
2224 GEOMImpl_ILocalOperations* aLocalOperations = new GEOMImpl_ILocalOperations(GetEngine(), GetDocID());
2225 std::vector<GEOM_IOperations*> theOperations;
2226 theOperations.push_back(a3DPrimOperations);
2227 theOperations.push_back(aBasicOperations);
2228 theOperations.push_back(aBlocksOperations);
2229 theOperations.push_back(aBooleanOperations);
2230 theOperations.push_back(aShapesOperations);
2231 theOperations.push_back(aTransformOperations);
2234 TopoDS_Shape aShapeShape = aShape->GetValue();
2235 TopTools_IndexedMapOfShape anEdgesIndices;
2236 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2237 // Common edges on external cylinders
2238 Handle(GEOM_Object) box_e;
2240 box_e = a3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2243 box_e = a3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2245 box_e->GetLastFunction()->SetDescription("");
2246 box_e = aTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2247 box_e->GetLastFunction()->SetDescription("");
2249 Handle(TColStd_HSequenceOfInteger) edges_e = aShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2250 box_e->GetLastFunction()->SetDescription("");
2252 if (edges_e.IsNull() || edges_e->Length() == 0) {
2253 // std::cerr << "Internal edges not found" << std::endl;
2254 SetErrorCode("External edges not found");
2257 // std::cerr << "External edges found" << std::endl;
2258 int nbEdgesInFillet = 0;
2259 std::list<int> theEdges;
2260 for (int i=1; i<=edges_e->Length();i++) {
2261 // Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
2262 // anObj->GetLastFunction()->SetDescription("");
2263 int edgeID = edges_e->Value(i);
2264 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2265 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2267 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2268 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2270 theEdges.push_back(edgeID);
2274 if (theHexMesh && nbEdgesInFillet == 1)
2278 Handle(GEOM_Object) aFillet = aLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2279 aFillet->GetLastFunction()->SetDescription("");
2281 TopoDS_Shape aFilletShape = aFillet->GetValue();
2282 aFunction->SetValue(aFilletShape);
2286 std::cerr << "Creating partition" << std::endl;
2287 if (!MakePipeTShapePartition(/*theOperations, */aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2289 std::cerr << "Done" << std::endl;
2290 std::cerr << "Creating mirrors and glue" << std::endl;
2291 if (!MakePipeTShapeMirrorAndGlue(/*theOperations, */aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2293 std::cerr << "Done" << std::endl;
2296 TopoDS_Shape Te = aShape->GetValue();
2299 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2300 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
2301 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2302 aFunction->SetValue(aTrsf_Shape);
2303 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2304 aSeq->Append(aShape);
2307 * Get the groups: BEGIN
2309 if (!MakeGroups(/*theOperations, */aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, aTrsf))
2312 TCollection_AsciiString aListRes, anEntry;
2313 // Iterate over the sequence aSeq
2314 Standard_Integer aNbGroups = aSeq->Length();
2315 Standard_Integer i = 2;
2316 for (; i <= aNbGroups; i++) {
2317 Handle(Standard_Transient) anItem = aSeq->Value(i);
2318 if (anItem.IsNull()) continue;
2319 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2320 if (aGroup.IsNull()) continue;
2321 //Make a Python command
2322 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2323 aListRes += anEntry + ", ";
2326 aListRes.Trunc(aListRes.Length() - 2);
2328 //Make a Python command
2329 GEOM::TPythonDump(aFunction) << "[" << aShape << ", " << aListRes.ToCString()
2330 << "] = geompy.MakePipeTShapeFillet(" << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2
2331 << ", " << theW2 << ", " << theL2 << ", " << theRF << ", " << theHexMesh << ", " << theP1 << ", "
2332 << theP2 << ", " << theP3 << ")";
2335 * Get the groups: END
2338 //Make a Python command
2339 GEOM::TPythonDump(aFunction) << "[" << aShape << "] = geompy.MakePipeTShapeFillet(" << theR1 << ", " << theW1
2340 << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theRF << ", "
2341 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3 << ")";
2349 /*@@ insert new functions before this line @@*/