1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File : GEOMImpl_IAdvancedOperations.cxx
21 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
24 #include <Standard_Stream.hxx>
25 #include "GEOMImpl_Types.hxx"
26 #include "GEOMImpl_IAdvancedOperations.hxx"
27 #include "GEOMImpl_IBasicOperations.hxx"
28 #include "GEOMImpl_IBooleanOperations.hxx"
29 #include "GEOMImpl_IShapesOperations.hxx"
30 #include "GEOMImpl_ITransformOperations.hxx"
31 #include "GEOMImpl_IBlocksOperations.hxx"
32 #include "GEOMImpl_I3DPrimOperations.hxx"
33 #include "GEOMImpl_ILocalOperations.hxx"
35 #include "GEOMImpl_Gen.hxx"
37 #include <utilities.h>
39 #include <Utils_ExceptHandlers.hxx>
41 #include "GEOM_Function.hxx"
42 #include "GEOM_PythonDump.hxx"
44 #include "GEOMImpl_PipeTShapeDriver.hxx"
45 #include "GEOMImpl_IPipeTShape.hxx"
46 /*@@ insert new functions before this line @@ do not remove this line @@ do not remove this line @@*/
49 #include <TopExp_Explorer.hxx>
51 #include <TopoDS_Vertex.hxx>
52 #include <TopTools_IndexedMapOfShape.hxx>
57 #include <BRepBuilderAPI_Transform.hxx>
58 #include <BRep_Tool.hxx>
61 #include <TFunction_DriverTable.hxx>
62 #include <TFunction_Driver.hxx>
63 #include <TFunction_Logbook.hxx>
64 #include <TDF_Tool.hxx>
65 #include <Standard_Failure.hxx>
66 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
68 #define HALF_LENGTH_MAIN_PIPE "Main pipe half length" //"Tuyau principal - demi longueur"
69 #define HALF_LENGTH_INCIDENT_PIPE "Incident pipe half length" //"Tuyau incident - demi longueur"
70 #define CIRCULAR_QUARTER_PIPE "Circular quarter of pipe" //"Circulaire - quart de tuyau"
71 #define THICKNESS "Thickness" //"Epaisseur"
72 #define FLANGE "Flange" // "Collerette"
73 #define CHAMFER_OR_FILLET "Chamfer or fillet" //"Chanfrein ou Raccord"
74 #define JUNCTION_FACE_1 "Junction 1" //"Face de jonction 1"
75 #define JUNCTION_FACE_2 "Junction 2" //"Face de jonction 2"
76 #define JUNCTION_FACE_3 "Junction 3" //"Face de jonction 3"
78 //=============================================================================
82 //=============================================================================
83 GEOMImpl_IAdvancedOperations::GEOMImpl_IAdvancedOperations(GEOM_Engine* theEngine, int theDocID) :
84 GEOM_IOperations(theEngine, theDocID)
86 MESSAGE("GEOMImpl_IAdvancedOperations::GEOMImpl_IAdvancedOperations");
87 myBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
88 myBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
89 myShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
90 myTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
91 myBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
92 my3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
93 myLocalOperations = new GEOMImpl_ILocalOperations(GetEngine(), GetDocID());
96 //=============================================================================
100 //=============================================================================
101 GEOMImpl_IAdvancedOperations::~GEOMImpl_IAdvancedOperations()
103 MESSAGE("GEOMImpl_IAdvancedOperations::~GEOMImpl_IAdvancedOperations");
104 delete myBasicOperations;
105 delete myBooleanOperations;
106 delete myShapesOperations;
107 delete myTransformOperations;
108 delete myBlocksOperations;
109 delete my3DPrimOperations;
110 delete myLocalOperations;
113 //=============================================================================
117 //=============================================================================
118 gp_Trsf GEOMImpl_IAdvancedOperations::GetPositionTrsf(double theL1, double theL2,
119 Handle(GEOM_Object) theP1,
120 Handle(GEOM_Object) theP2,
121 Handle(GEOM_Object) theP3)
123 // Old Local Coordinates System oldLCS
125 gp_Pnt P1(-theL1, 0, 0);
126 gp_Pnt P2(theL1, 0, 0);
127 gp_Pnt P3(0, 0, theL2);
129 gp_Dir oldX(gp_Vec(P1, P2));
130 gp_Dir oldZ(gp_Vec(P0, P3));
131 gp_Ax3 oldLCS(P0, oldZ, oldX);
133 // New Local Coordinates System newLCS
134 double LocX, LocY, LocZ;
135 gp_Pnt newP1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
136 gp_Pnt newP2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
137 gp_Pnt newP3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
138 LocX = (newP1.X() + newP2.X()) / 2.;
139 LocY = (newP1.Y() + newP2.Y()) / 2.;
140 LocZ = (newP1.Z() + newP2.Z()) / 2.;
141 gp_Pnt newO(LocX, LocY, LocZ);
143 gp_Dir newX(gp_Vec(newP1, newP2)); // P1P2 Vector
144 gp_Dir newZ(gp_Vec(newO, newP3)); // OP3 Vector
145 gp_Ax3 newLCS = gp_Ax3(newO, newZ, newX);
148 aTrsf.SetDisplacement(oldLCS, newLCS);
153 //=============================================================================
155 * CheckCompatiblePosition
158 //=============================================================================
159 bool GEOMImpl_IAdvancedOperations::CheckCompatiblePosition(double& theL1, double& theL2,
160 Handle(GEOM_Object) theP1,
161 Handle(GEOM_Object) theP2,
162 Handle(GEOM_Object) theP3,
166 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
167 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
168 gp_Pnt P3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
170 double d12 = P1.Distance(P2);
171 double d13 = P1.Distance(P3);
172 double d23 = P2.Distance(P3);
173 // double d2 = newO.Distance(P3);
175 if (Abs(d12) <= Precision::Confusion()) {
176 SetErrorCode("Junctions points P1 and P2 are identical");
179 if (Abs(d13) <= Precision::Confusion()) {
180 SetErrorCode("Junctions points P1 and P3 are identical");
183 if (Abs(d23) <= Precision::Confusion()) {
184 SetErrorCode("Junctions points P2 and P3 are identical");
189 double newL1 = 0.5 * d12;
190 double newL2 = sqrt(pow(d13,2)-pow(newL1,2));
192 // theL1*(1-theTolerance) <= newL1 <= theL1*(1+theTolerance)
194 if (fabs(newL1 - theL1) > Precision::Approximation()) {
195 if ( (newL1 * (1 - theTolerance) -theL1 <= Precision::Approximation()) &&
196 (newL1 * (1 + theTolerance) -theL1 >= Precision::Approximation()) ) {
197 // std::cerr << "theL1 = newL1" << std::endl;
201 SetErrorCode("Dimension for main pipe (L1) is incompatible with new position");
207 // theL2*(1-theTolerance) <= newL2 <= theL2*(1+theTolerance)
209 if (fabs(newL2 - theL2) > Precision::Approximation()) {
210 if ( (newL2 * (1 - theTolerance) -theL2 <= Precision::Approximation()) &&
211 (newL2 * (1 + theTolerance) -theL2 >= Precision::Approximation()) ) {
215 SetErrorCode("Dimension for incident pipe (L2) is incompatible with new position");
225 //=============================================================================
227 * Generate the propagation groups of a Pipe T-Shape used for hexa mesh
229 //=============================================================================
230 bool GEOMImpl_IAdvancedOperations::MakeGroups(Handle(GEOM_Object) theShape, int shapeType,
231 double theR1, double theW1, double theL1,
232 double theR2, double theW2, double theL2,
233 Handle(TColStd_HSequenceOfTransient) theSeq,
238 if (theShape.IsNull()) return false;
240 TopoDS_Shape aShape = theShape->GetValue();
241 if (aShape.IsNull()) {
242 SetErrorCode("Shape is not defined");
246 gp_Trsf aTrsfInv = aTrsf.Inverted();
248 int expectedGroups = 0;
249 if (shapeType == TSHAPE_BASIC)
250 if (Abs(theR2+theW2-theR1-theW1) <= Precision::Approximation())
254 else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET)
257 double aR1Ext = theR1 + theW1;
258 double aR2Ext = theR2 + theW2;
260 /////////////////////////
261 //// Groups of Faces ////
262 /////////////////////////
265 // Comment the following lines when GetInPlace bug is solved
267 // Workaround of GetInPlace bug
268 // Create a bounding box that fits the shape
269 Handle(GEOM_Object) aBox = my3DPrimOperations->MakeBoxDXDYDZ(2*theL1, 2*aR1Ext, aR1Ext+theL2);
270 aBox->GetLastFunction()->SetDescription("");
271 myTransformOperations->TranslateDXDYDZ(aBox, -theL1, -aR1Ext, -aR1Ext);
272 aBox->GetLastFunction()->SetDescription("");
273 // Apply transformation to box
274 BRepBuilderAPI_Transform aTransformationBox(aBox->GetValue(), aTrsf, Standard_False);
275 TopoDS_Shape aBoxShapeTrsf = aTransformationBox.Shape();
276 aBox->GetLastFunction()->SetValue(aBoxShapeTrsf);
278 // Get the shell of the box
279 Handle(GEOM_Object) aShell = Handle(GEOM_Object)::DownCast(myShapesOperations->MakeExplode(aBox, TopAbs_SHELL, true)->Value(1));
280 aBox->GetLastFunction()->SetDescription("");
281 aShell->GetLastFunction()->SetDescription("");
282 // Get the common shapes between shell and shape
283 Handle(GEOM_Object) aCommonCompound = myBooleanOperations->MakeBoolean (theShape, aShell, 1); // MakeCommon
284 aCommonCompound->GetLastFunction()->SetDescription("");
285 // Explode the faces of common shapes => 3 faces
286 Handle(TColStd_HSequenceOfTransient) aCommonFaces = myShapesOperations->MakeExplode(aCommonCompound, TopAbs_FACE, true);
287 aCommonCompound->GetLastFunction()->SetDescription("");
288 std::list<Handle(GEOM_Object)> aCompoundOfFacesList;
290 for (int i=0 ; i<= aCommonFaces->Length()-4 ; i+=4) {
291 std::list<Handle(GEOM_Object)> aFacesList;
292 for (int j = 1 ; j <= 4 ; j++) {
293 Handle(GEOM_Object) aFace = Handle(GEOM_Object)::DownCast(aCommonFaces->Value(i+j)); // Junction faces
294 if (!aFace.IsNull()) {
295 aFace->GetLastFunction()->SetDescription("");
296 aFacesList.push_back(aFace);
299 Handle(GEOM_Object) aCompoundOfFaces = myShapesOperations->MakeCompound(aFacesList);
300 if (!aCompoundOfFaces.IsNull()) {
301 aCompoundOfFaces->GetLastFunction()->SetDescription("");
302 aCompoundOfFacesList.push_back(aCompoundOfFaces);
306 if (aCompoundOfFacesList.size() == 3) {
307 Handle(GEOM_Object) aPln1 = aCompoundOfFacesList.front();
308 aCompoundOfFacesList.pop_front();
309 Handle(GEOM_Object) aPln2 = aCompoundOfFacesList.front();
310 aCompoundOfFacesList.pop_front();
311 Handle(GEOM_Object) aPln3 = aCompoundOfFacesList.front();
312 aCompoundOfFacesList.pop_front();
317 // Uncomment the following lines when GetInPlace bug is solved
319 // Handle(GEOM_Object) aP1 = myBasicOperations->MakePointXYZ(-theL1, 0, 0);
320 // Handle(GEOM_Object) aP2 = myBasicOperations->MakePointXYZ(-0, 0, theL2);
321 // Handle(GEOM_Object) aP3 = myBasicOperations->MakePointXYZ(theL1, 0, 0);
322 // aP1->GetLastFunction()->SetDescription("");
323 // aP2->GetLastFunction()->SetDescription("");
324 // aP3->GetLastFunction()->SetDescription("");
325 // Handle(GEOM_Object) aV1 = myBasicOperations->MakeVectorDXDYDZ(-1, 0, 0);
326 // Handle(GEOM_Object) aV2 = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
327 // Handle(GEOM_Object) aV3 = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
328 // aV1->GetLastFunction()->SetDescription("");
329 // aV2->GetLastFunction()->SetDescription("");
330 // aV3->GetLastFunction()->SetDescription("");
331 // Handle(GEOM_Object) aPln1 = myBasicOperations->MakePlanePntVec(aP1, aV1, 2*(theR1+theW1+theL2));
332 // Handle(GEOM_Object) aPln2 = myBasicOperations->MakePlanePntVec(aP2, aV2, 2*(theR2+theW2));
333 // Handle(GEOM_Object) aPln3 = myBasicOperations->MakePlanePntVec(aP3, aV3, 2*(theR1+theW1+theL2));
334 // aPln1->GetLastFunction()->SetDescription("");
335 // aPln2->GetLastFunction()->SetDescription("");
336 // aPln3->GetLastFunction()->SetDescription("");
338 // BRepBuilderAPI_Transform aTransformation1(aPln1->GetValue(), aTrsf, Standard_False);
339 // TopoDS_Shape aTrsf_Shape1 = aTransformation1.Shape();
340 // aPln1->GetLastFunction()->SetValue(aTrsf_Shape1);
341 // BRepBuilderAPI_Transform aTransformation2(aPln2->GetValue(), aTrsf, Standard_False);
342 // TopoDS_Shape aTrsf_Shape2 = aTransformation2.Shape();
343 // aPln2->GetLastFunction()->SetValue(aTrsf_Shape2);
344 // BRepBuilderAPI_Transform aTransformation3(aPln3->GetValue(), aTrsf, Standard_False);
345 // TopoDS_Shape aTrsf_Shape3 = aTransformation3.Shape();
346 // aPln3->GetLastFunction()->SetValue(aTrsf_Shape3);
350 Handle(GEOM_Object) junctionFaces1 = myShapesOperations->GetInPlace(theShape, aPln1);
351 if (junctionFaces1.IsNull())
352 junctionFaces1 = myShapesOperations->GetShapesOnShapeAsCompound(aPln1, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
353 if (!junctionFaces1.IsNull()) {
354 junctionFaces1->GetLastFunction()->SetDescription("");
355 junctionFaces1->SetName("JUNCTION_FACE_1");
356 theSeq->Append(junctionFaces1);
359 SetErrorCode("Junction face 1 not found");
360 // theSeq->Append(aPln1);
363 Handle(GEOM_Object) junctionFaces2 = myShapesOperations->GetInPlace(theShape, aPln2);
364 if (junctionFaces2.IsNull())
365 junctionFaces2 = myShapesOperations->GetShapesOnShapeAsCompound(aPln2, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
366 if (!junctionFaces2.IsNull()) {
367 junctionFaces2->GetLastFunction()->SetDescription("");
368 junctionFaces2->SetName("JUNCTION_FACE_2");
369 theSeq->Append(junctionFaces2);
372 SetErrorCode("Junction face 2 not found");
373 // theSeq->Append(aPln2);
376 Handle(GEOM_Object) junctionFaces3 = myShapesOperations->GetInPlace(theShape, aPln3);
377 if (junctionFaces3.IsNull())
378 junctionFaces3 = myShapesOperations->GetShapesOnShapeAsCompound(aPln3, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
379 if (!junctionFaces3.IsNull()) {
380 junctionFaces3->GetLastFunction()->SetDescription("");
381 junctionFaces3->SetName("JUNCTION_FACE_3");
382 theSeq->Append(junctionFaces3);
385 SetErrorCode("Junction face 3 not found");
386 // theSeq->Append(aPln3);
390 /////////////////////////
391 //// Groups of Edges ////
392 /////////////////////////
393 // Result of propagate
395 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
397 TCollection_AsciiString theDesc = aFunction->GetDescription();
398 Handle(TColStd_HSequenceOfTransient) aSeqPropagate = myBlocksOperations->Propagate(theShape);
399 if (aSeqPropagate.IsNull() || aSeqPropagate->Length() == 0) {
400 SetErrorCode("Propagation groups not found");
403 Standard_Integer nbEdges, aNbGroups = aSeqPropagate->Length();
404 // Recover previous description to get rid of Propagate dump
405 aFunction->SetDescription(theDesc);
408 bool circularFoundAndAdded = false;
409 bool incidentPipeFound = false;
410 bool mainPipeFound = false;
411 bool mainPipeFoundAndAdded = false;
412 bool radialFound =false;
413 bool flangeFound = false;
414 bool flangeFoundAndAdded = false;
415 bool chamferOrFilletFound = false;
417 for (int i=1 ; i<= aNbGroups; i++) {
420 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
424 TopoDS_Shape aGroupShape = aGroup->GetValue();
425 BRepBuilderAPI_Transform aTransformationShapeInv(aGroupShape, aTrsfInv, Standard_False);
426 TopoDS_Shape aGroupShapeTrsfInv = aTransformationShapeInv.Shape();
428 TopTools_IndexedMapOfShape anEdgesMap;
429 TopExp::MapShapes(aGroupShapeTrsfInv,TopAbs_EDGE, anEdgesMap);
430 nbEdges = anEdgesMap.Extent();
432 if (shapeType == TSHAPE_BASIC) {
433 if ((nbEdges == 21) || /*R1Ext = R2Ext*/(nbEdges == 17)){
435 aGroup->SetName("THICKNESS");
437 else if (nbEdges == 6) {
438 if (!circularFoundAndAdded) {
439 circularFoundAndAdded = true;
441 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
444 else if (nbEdges == 8) {
445 incidentPipeFound = true;
446 mainPipeFound = false;
450 TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
452 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
453 double x=aP.X(), y=aP.Y(), z=aP.Z();
456 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
457 (Abs(y) > aR2Ext + Precision::Confusion())) {
458 incidentPipeFound = false;
461 if ( z < -Precision::Confusion()) {
462 // length of main pipe
463 mainPipeFound = true;
464 if (!mainPipeFoundAndAdded) {
465 mainPipeFoundAndAdded = true;
467 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
471 else if (Abs(x) > (theL1-Precision::Confusion())) {
472 // discretisation circulaire
474 if (!circularFoundAndAdded) {
475 circularFoundAndAdded = true;
477 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
482 if (incidentPipeFound) {
484 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
486 if (!addGroup && (!incidentPipeFound &&
490 // Flange (collerette)
493 aGroup->SetName("FLANGE");
499 else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
502 aGroup->SetName("THICKNESS");
504 else if ((nbEdges == 10) || (nbEdges == 6)) {
505 if (!circularFoundAndAdded) {
507 circularFoundAndAdded = true;
508 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
511 else if (nbEdges == 8) {
512 incidentPipeFound = true;
513 mainPipeFound = false;
516 TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
518 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
519 double x=aP.X(), y=aP.Y(), z=aP.Z();
521 // tuy_princ_long_avant & tuy_princ_long_apres
522 bool isMain = (((z < Precision::Confusion()) || (x < Precision::Confusion())) &&
523 ((y <= aR1Ext + Precision::Confusion()) ||
524 (y <= -(aR1Ext + Precision::Confusion())) ||
525 (y <= theR1 + Precision::Confusion()) ||
526 (y == -(theR1 + Precision::Confusion()))));
530 mainPipeFound = false;
534 if (z < Precision::Confusion()) {
536 if (!flangeFoundAndAdded) {
537 flangeFoundAndAdded = true;
539 aGroup->SetName("FLANGE");
544 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
545 (Abs(y) > aR2Ext + Precision::Confusion())) {
546 incidentPipeFound = false;
552 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
554 if (incidentPipeFound) {
556 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
558 if (!addGroup && (!incidentPipeFound &&
561 !chamferOrFilletFound)) {
563 chamferOrFilletFound = true;
564 if (shapeType == TSHAPE_CHAMFER)
565 aGroup->SetName("CHAMFER");
567 aGroup->SetName("FILLET");
573 // Add group to the list
575 theSeq->Append(aGroup);
582 bool GEOMImpl_IAdvancedOperations::MakePipeTShapePartition(Handle(GEOM_Object) theShape,
583 double theR1, double theW1, double theL1,
584 double theR2, double theW2, double theL2,
585 double theH, double theW,
586 double theRF, bool isNormal)
590 // Build tools for partition operation:
591 // 1 face and 2 planes
593 Handle(GEOM_Object) arete_intersect_int;
594 Handle(GEOM_Object) wire_t, wire_t2, face_t, face_t2;
595 Handle(GEOM_Object) chan_racc;
596 Handle(GEOM_Object) vi1, vi2;
598 Handle(GEOM_Object) Vector_Z = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
599 Vector_Z->GetLastFunction()->SetDescription("");
602 double aSize = 2*(theL1 + theL2);
603 double aR1Ext = theR1 + theW1;
604 double aR2Ext = theR2 + theW2;
605 double theVertCylinderRadius = aR2Ext + theW + theRF;
606 double theHoriCylinderRadius = aR1Ext + theH + theRF;
608 // Common edges on internal cylinder
609 Handle(GEOM_Object) box_i = my3DPrimOperations->MakeBoxDXDYDZ(theR2, theR2, theR1);
610 box_i->GetLastFunction()->SetDescription("");
611 box_i = myTransformOperations->TranslateDXDYDZ(box_i, -theR2, -theR2, 0);
612 box_i->GetLastFunction()->SetDescription("");
614 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
615 TCollection_AsciiString theDesc = aFunction->GetDescription();
616 Handle(TColStd_HSequenceOfTransient) edges_i = myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
617 // Recover previous description to get rid of Propagate dump
618 aFunction->SetDescription(theDesc);
619 if (edges_i.IsNull() || edges_i->Length() == 0) {
620 SetErrorCode("Internal edges not found");
623 for (int i=1; i<=edges_i->Length();i++) {
624 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_i->Value(i));
625 anObj->GetLastFunction()->SetDescription("");
627 arete_intersect_int = Handle(GEOM_Object)::DownCast(edges_i->Value(1));
629 // search for vertices located on both internal pipes
630 aFunction = theShape->GetLastFunction();
631 theDesc = aFunction->GetDescription();
632 Handle(TColStd_HSequenceOfTransient) vertices_i = myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
633 // Recover previous description to get rid of Propagate dump
634 aFunction->SetDescription(theDesc);
635 if (vertices_i.IsNull() || vertices_i->Length() == 0) {
636 SetErrorCode("Internal vertices not found");
640 for (int i = 1; i <= vertices_i->Length(); i++) {
641 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_i->Value(i));
642 v->GetLastFunction()->SetDescription("");
643 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
644 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
645 if (Abs(aP.X()) <= Precision::Confusion()) {
646 if (Abs(aP.Y()) - theR2 <= Precision::Confusion())
648 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
649 if (Abs(aP.X()) - theR1 <= Precision::Confusion())
654 std::list<Handle(GEOM_Object)> theShapes;
657 Handle(GEOM_Object) ve1, ve2;
659 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ(aR2Ext, aR2Ext, aR1Ext);
660 box_e->GetLastFunction()->SetDescription("");
661 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -aR2Ext, -aR2Ext, 0);
662 box_e->GetLastFunction()->SetDescription("");
663 // Common edges on external cylinder
664 aFunction = theShape->GetLastFunction();
665 theDesc = aFunction->GetDescription();
666 Handle(TColStd_HSequenceOfTransient) edges_e = myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
667 // Recover previous description to get rid of Propagate dump
668 aFunction->SetDescription(theDesc);
669 if (edges_e.IsNull() || edges_e->Length() == 0) {
670 SetErrorCode("External edges not found");
673 for (int i=1; i<=edges_e->Length();i++) {
674 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
675 anObj->GetLastFunction()->SetDescription("");
678 // search for vertices located on both external pipes
679 aFunction = theShape->GetLastFunction();
680 theDesc = aFunction->GetDescription();
681 Handle(TColStd_HSequenceOfTransient) vertices_e = myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
682 // Recover previous description to get rid of Propagate dump
683 aFunction->SetDescription(theDesc);
684 if (vertices_e.IsNull() || vertices_e->Length() == 0) {
685 SetErrorCode("External vertices not found");
689 for (int i = 1; i <= vertices_e->Length(); i++) {
690 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_e->Value(i));
691 v->GetLastFunction()->SetDescription("");
692 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
693 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
694 if (Abs(aP.X()) <= Precision::Confusion()) {
695 if (Abs(aP.Y()) - theR2 > Precision::Confusion())
697 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
698 if (Abs(aP.X()) - theR2 > Precision::Confusion())
702 Handle(GEOM_Object) edge_e1, edge_e2;
704 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
707 edge_e1 = myBasicOperations->MakeLineTwoPnt(ve1, vi1);
708 if (edge_e1.IsNull()) {
709 SetErrorCode("Edge 1 could not be built");
712 } catch (Standard_Failure) {
713 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
714 SetErrorCode(aFail->GetMessageString());
719 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
722 edge_e2 = myBasicOperations->MakeLineTwoPnt(ve2, vi2);
723 if (edge_e2.IsNull()) {
724 SetErrorCode("Edge 2 could not be built");
727 } catch (Standard_Failure) {
728 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
729 SetErrorCode(aFail->GetMessageString());
733 edge_e1->GetLastFunction()->SetDescription("");
734 edge_e2->GetLastFunction()->SetDescription("");
736 std::list<Handle(GEOM_Object)> edge_e_elist;
737 edge_e_elist.push_back(arete_intersect_int);
738 edge_e_elist.push_back(edge_e1);
739 edge_e_elist.push_back(Handle(GEOM_Object)::DownCast(edges_e->Value(1)));
740 edge_e_elist.push_back(edge_e2);
741 wire_t = myShapesOperations->MakeWire(edge_e_elist, 1e-7);
742 if (wire_t.IsNull()) {
743 SetErrorCode("Impossible to build wire");
746 wire_t->GetLastFunction()->SetDescription("");
747 face_t = myShapesOperations->MakeFace(wire_t, false);
748 if (face_t.IsNull()) {
749 SetErrorCode("Impossible to build face");
752 face_t->GetLastFunction()->SetDescription("");
755 Handle(GEOM_Object) P1, P2, P3, P4, P5, P6;
756 int idP1, idP2, idP3, idP4;
761 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ(theVertCylinderRadius, theVertCylinderRadius, theHoriCylinderRadius);
762 box_e->GetLastFunction()->SetDescription("");
763 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -theVertCylinderRadius, -theVertCylinderRadius, 0);
764 box_e->GetLastFunction()->SetDescription("");
766 aFunction = theShape->GetLastFunction();
767 theDesc = aFunction->GetDescription();
768 Handle(TColStd_HSequenceOfTransient) extremVertices = myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
769 // Recover previous description to get rid of Propagate dump
770 aFunction->SetDescription(theDesc);
772 if (extremVertices.IsNull() || extremVertices->Length() == 0) {
774 SetErrorCode("Vertices on chamfer not found");
776 SetErrorCode("Vertices on fillet not found");
780 theShapes.push_back(theShape);
781 theShapes.push_back(box_e);
782 if (extremVertices->Length() != 6) {
783 // for (int i=1; i<=extremVertices->Length(); i++){
784 // theShapes.push_back(Handle(GEOM_Object)::DownCast(extremVertices->Value(i)));
786 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
787 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
788 // theShape->GetLastFunction()->SetValue(aCompoundShape);
789 SetErrorCode("Bad number of vertices on chamfer found");
793 for (int i=1; i<=extremVertices->Length(); i++){
794 Handle(GEOM_Object) aV = Handle(GEOM_Object)::DownCast(extremVertices->Value(i));
795 aV->GetLastFunction()->SetDescription("");
796 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aV->GetValue()));
798 if (Abs(aP.X()) <= Precision::Confusion()) {
799 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
801 if (aP.Z()-ZX > Precision::Confusion()) {
808 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
810 if (aP.Z() - ZY > Precision::Confusion()) {
827 P1 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP1));
828 P2 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP2));
829 P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
830 P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4));
832 Handle(GEOM_Object) Cote_1 = myBasicOperations->MakeLineTwoPnt(P1, vi1);
833 if (Cote_1.IsNull()) {
834 SetErrorCode("Impossible to build edge in thickness");
837 Cote_1->GetLastFunction()->SetDescription("");
839 Handle(GEOM_Object) Cote_2 = myBasicOperations->MakeLineTwoPnt(vi2, P3);
840 if (Cote_2.IsNull()) {
841 SetErrorCode("Impossible to build edge in thickness");
844 Cote_2->GetLastFunction()->SetDescription("");
846 // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
847 // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
848 // std::cerr << "Getting chamfer edge on main pipe" << std::endl;
849 Handle(GEOM_Object) edge_chan_princ = myBlocksOperations->GetEdge(theShape, P1, P3);
850 if (edge_chan_princ.IsNull()) {
851 SetErrorCode("Impossible to find edge on main pipe");
854 edge_chan_princ->GetLastFunction()->SetDescription("");
856 Handle(GEOM_Object) edge_chan_inc = myBlocksOperations->GetEdge(theShape, P2, P4);
857 if (edge_chan_inc.IsNull()) {
858 SetErrorCode("Impossible to find edge on incident pipe");
861 edge_chan_inc->GetLastFunction()->SetDescription("");
863 std::list<Handle(GEOM_Object)> edgeList1;
864 edgeList1.push_back(edge_chan_princ);
865 edgeList1.push_back(Cote_1);
866 edgeList1.push_back(arete_intersect_int);
867 edgeList1.push_back(Cote_2);
869 // std::cerr << "Creating wire 1" << std::endl;
870 wire_t = myShapesOperations->MakeWire(edgeList1, 1e-7);
871 if (wire_t.IsNull()) {
872 SetErrorCode("Impossible to build wire");
875 wire_t->GetLastFunction()->SetDescription("");
877 // std::cerr << "Creating face 1" << std::endl;
878 face_t = myShapesOperations->MakeFace(wire_t, false);
879 if (face_t.IsNull()) {
880 SetErrorCode("Impossible to build face");
883 face_t->GetLastFunction()->SetDescription("");
884 theShapes.push_back(face_t);
886 gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(P2->GetValue()));
887 gp_Pnt aP5 = BRep_Tool::Pnt(TopoDS::Vertex(vi1->GetValue()));
888 double deltaZ = aP2.Z() - aP5.Z();
889 // std::cerr << "Creating new point from vi1 with deltaZ = " << deltaZ << std::endl;
890 Handle(GEOM_Object) P5bis = myTransformOperations->TranslateDXDYDZCopy(vi1, 0, 0, deltaZ);
891 if (P5bis.IsNull()) {
892 SetErrorCode("Impossible to translate vertex");
895 P5bis->GetLastFunction()->SetDescription("");
897 gp_Pnt aP4 = BRep_Tool::Pnt(TopoDS::Vertex(P4->GetValue()));
898 gp_Pnt aP6 = BRep_Tool::Pnt(TopoDS::Vertex(vi2->GetValue()));
899 deltaZ = aP4.Z() - aP6.Z();
900 // std::cerr << "Creating new point from vi2 with deltaZ = " << deltaZ << std::endl;
901 Handle(GEOM_Object) P6bis = myTransformOperations->TranslateDXDYDZCopy(vi2, 0, 0, deltaZ);
902 if (P6bis.IsNull()) {
903 SetErrorCode("Impossible to translate vertex");
906 P6bis->GetLastFunction()->SetDescription("");
908 // std::cerr << "Creating new line 1 from 2 previous points" << std::endl;
909 Handle(GEOM_Object) Cote_3 = myBasicOperations->MakeLineTwoPnt(P5bis, P2);
910 if (Cote_3.IsNull()) {
911 SetErrorCode("Impossible to build edge in thickness");
914 Cote_3->GetLastFunction()->SetDescription("");
916 // std::cerr << "Creating new line 2 from 2 previous points" << std::endl;
917 Handle(GEOM_Object) Cote_4 = myBasicOperations->MakeLineTwoPnt(P6bis, P4);
918 if (Cote_4.IsNull()) {
919 SetErrorCode("Impossible to build edge in thickness");
922 Cote_4->GetLastFunction()->SetDescription("");
924 // std::cerr << "Creating new line 3 from 2 previous points" << std::endl;
925 Handle(GEOM_Object) Cote_5 = myBasicOperations->MakeLineTwoPnt(P5bis, P6bis);
926 if (Cote_4.IsNull()) {
927 SetErrorCode("Impossible to build edge in thickness");
930 Cote_5->GetLastFunction()->SetDescription("");
932 std::list<Handle(GEOM_Object)> edgeList2;
933 edgeList2.push_back(edge_chan_inc);
934 edgeList2.push_back(Cote_3);
935 edgeList2.push_back(Cote_5);
936 edgeList2.push_back(Cote_4);
937 // std::cerr << "Creating wire 2" << std::endl;
938 wire_t2 = myShapesOperations->MakeWire(edgeList2, 1e-7);
939 if (wire_t2.IsNull()) {
940 SetErrorCode("Impossible to build wire");
943 wire_t2->GetLastFunction()->SetDescription("");
944 // std::cerr << "Creating face 2" << std::endl;
945 face_t2 = myShapesOperations->MakeFace(wire_t2, false);
946 if (face_t2.IsNull()) {
947 SetErrorCode("Impossible to build face");
950 face_t2->GetLastFunction()->SetDescription("");
951 theShapes.push_back(face_t2);
955 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
956 Handle(GEOM_Object) aVZ = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
957 Handle(GEOM_Object) aVXZ = myBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
958 Handle(GEOM_Object) aPlnOZ = myBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
959 Handle(GEOM_Object) aPlnOXZ = myBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
960 aP0->GetLastFunction()->SetDescription("");
961 aVZ->GetLastFunction()->SetDescription("");
962 aVXZ->GetLastFunction()->SetDescription("");
963 aPlnOZ->GetLastFunction()->SetDescription("");
964 aPlnOXZ->GetLastFunction()->SetDescription("");
965 theShapes.push_back(aPlnOZ);
966 theShapes.push_back(aPlnOXZ);
969 Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
970 Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
971 Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
972 Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
973 Handle(TColStd_HArray1OfInteger) theMaterials;
974 partitionShapes->Append(theShape);
975 theTools->Append(aPlnOZ);
976 if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
977 theTools->Append(aPlnOXZ);
978 theTools->Append(face_t);
980 theTools->Append(face_t2);
982 Handle(GEOM_Object) Te3 = myBooleanOperations->MakePartition(partitionShapes, theTools, theKeepInside, theRemoveInside, TopAbs_SOLID, false, theMaterials, 0, false);
984 SetErrorCode("Impossible to build partition of TShape");
985 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
986 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
987 // theShape->GetLastFunction()->SetValue(aCompoundShape);
990 Te3->GetLastFunction()->SetDescription("");
993 TopoDS_Shape aShape = Te3->GetValue();
994 theShape->GetLastFunction()->SetValue(aShape);
1000 // Mirror and glue faces
1001 bool GEOMImpl_IAdvancedOperations::MakePipeTShapeMirrorAndGlue(Handle(GEOM_Object) theShape,
1002 double theR1, double theW1, double theL1,
1003 double theR2, double theW2, double theL2)
1008 double aSize = 2*(theL1 + theL2);
1009 double aR1Ext = theR1 + theW1;
1012 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1013 aP0->GetLastFunction()->SetDescription("");
1014 Handle(GEOM_Object) aVX = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
1015 Handle(GEOM_Object) aVY = myBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
1016 aVX->GetLastFunction()->SetDescription("");
1017 aVY->GetLastFunction()->SetDescription("");
1018 Handle(GEOM_Object) aPlane_OX = myBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
1019 Handle(GEOM_Object) aPlane_OY = myBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
1020 aPlane_OX->GetLastFunction()->SetDescription("");
1021 aPlane_OY->GetLastFunction()->SetDescription("");
1023 Handle(GEOM_Object) Te4 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
1025 SetErrorCode("Impossible to build mirror of quarter TShape");
1029 Handle(GEOM_Object) Te5 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
1031 SetErrorCode("Impossible to build mirror of half TShape");
1035 Handle(GEOM_Object) Te6 = myTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
1037 SetErrorCode("Impossible to build mirror of half TShape");
1041 std::list<Handle(GEOM_Object)> aShapesList;
1042 aShapesList.push_back(theShape);
1043 aShapesList.push_back(Te4);
1044 aShapesList.push_back(Te5);
1045 aShapesList.push_back(Te6);
1046 Handle(GEOM_Object) Te7 = myShapesOperations->MakeCompound(aShapesList);
1048 SetErrorCode("Impossible to build compound");
1052 Handle(GEOM_Object) Te8 = myShapesOperations->MakeGlueFaces(Te7, 1e-7, true);
1054 SetErrorCode("Impossible to glue faces of TShape");
1058 TopoDS_Shape aShape = Te8->GetValue();
1060 theShape->GetLastFunction()->SetValue(aShape);
1062 Te4->GetLastFunction()->SetDescription("");
1063 Te5->GetLastFunction()->SetDescription("");
1064 Te6->GetLastFunction()->SetDescription("");
1065 Te7->GetLastFunction()->SetDescription("");
1066 Te8->GetLastFunction()->SetDescription("");
1072 //=============================================================================
1075 * Create a T-shape object with specified caracteristics for the main and
1076 * the incident pipes (radius, width, half-length).
1077 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1078 * \param theR1 Internal radius of main pipe
1079 * \param theW1 Width of main pipe
1080 * \param theL1 Half-length of main pipe
1081 * \param theR2 Internal radius of incident pipe (R2 < R1)
1082 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1083 * \param theL2 Half-length of incident pipe
1084 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1085 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1087 //=============================================================================
1088 Handle(TColStd_HSequenceOfTransient)
1089 GEOMImpl_IAdvancedOperations::MakePipeTShape(double theR1, double theW1, double theL1,
1090 double theR2, double theW2, double theL2,
1093 MESSAGE("GEOMImpl_IAdvancedOperations::MakePipeTShape");
1096 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1098 //Add a new shape function with parameters
1099 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1100 if (aFunction.IsNull()) return NULL;
1102 //Check if the function is set correctly
1103 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
1105 GEOMImpl_IPipeTShape aData(aFunction);
1113 aData.SetHexMesh(theHexMesh);
1115 //Compute the resulting value
1117 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1120 if (!GetSolver()->ComputeFunction(aFunction)) {
1121 SetErrorCode("TShape driver failed");
1124 } catch (Standard_Failure) {
1125 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1126 SetErrorCode(aFail->GetMessageString());
1131 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1133 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1137 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1138 aSeq->Append(aShape);
1142 * Get the groups: BEGIN
1144 if (!MakeGroups(aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, gp_Trsf()))
1147 TCollection_AsciiString aListRes, anEntry;
1148 // Iterate over the sequence aSeq
1149 Standard_Integer aNbGroups = aSeq->Length();
1150 Standard_Integer i = 2;
1151 for (; i <= aNbGroups; i++) {
1152 Handle(Standard_Transient) anItem = aSeq->Value(i);
1153 if (anItem.IsNull()) continue;
1154 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
1155 if (aGroup.IsNull()) continue;
1156 //Make a Python command
1157 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
1158 aListRes += anEntry + ", ";
1161 aListRes.Trunc(aListRes.Length() - 2);
1163 //Make a Python command
1164 GEOM::TPythonDump(aFunction) << "[" << aShape << ", " << aListRes.ToCString() << "] = geompy.MakePipeTShape("
1165 << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", "
1166 << theHexMesh << ")";
1169 * Get the groups: END
1172 //Make a Python command
1173 GEOM::TPythonDump(aFunction) << "[" << aShape << "] = geompy.MakePipeTShape(" << theR1 << ", " << theW1 << ", "
1174 << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theHexMesh << ")";
1182 //=============================================================================
1184 * MakePipeTShapeWithPosition
1185 * Create a T-shape object with specified caracteristics for the main and
1186 * the incident pipes (radius, width, half-length).
1187 * The extremities of the main pipe are located on junctions points P1 and P2.
1188 * The extremity of the incident pipe is located on junction point P3.
1189 * \param theR1 Internal radius of main pipe
1190 * \param theW1 Width of main pipe
1191 * \param theL1 Half-length of main pipe
1192 * \param theR2 Internal radius of incident pipe (R2 < R1)
1193 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1194 * \param theL2 Half-length of incident pipe
1195 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1196 * \param theP1 1st junction point of main pipe
1197 * \param theP2 2nd junction point of main pipe
1198 * \param theP3 Junction point of incident pipe
1199 * \return List of GEOM_Objects, containing the created shape and propagation groups..
1201 //=============================================================================
1202 Handle(TColStd_HSequenceOfTransient)
1203 GEOMImpl_IAdvancedOperations::MakePipeTShapeWithPosition(double theR1, double theW1, double theL1,
1204 double theR2, double theW2, double theL2,
1206 Handle(GEOM_Object) theP1,
1207 Handle(GEOM_Object) theP2,
1208 Handle(GEOM_Object) theP3)
1212 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1216 //Add a new shape function with parameters
1217 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1218 if (aFunction.IsNull()) return NULL;
1220 //Check if the function is set correctly
1221 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
1223 // Check new position
1224 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
1228 GEOMImpl_IPipeTShape aData(aFunction);
1236 aData.SetHexMesh(theHexMesh);
1238 //Compute the resulting value
1240 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1243 if (!GetSolver()->ComputeFunction(aFunction)) {
1244 SetErrorCode("TShape driver failed");
1247 } catch (Standard_Failure) {
1248 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1249 SetErrorCode(aFail->GetMessageString());
1254 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1256 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1260 TopoDS_Shape Te = aShape->GetValue();
1263 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
1264 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
1265 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
1266 aFunction->SetValue(aTrsf_Shape);
1267 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1268 aSeq->Append(aShape);
1272 // Get the groups: BEGIN
1274 if (!MakeGroups(aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, aTrsf)) {
1278 TCollection_AsciiString aListRes, anEntry;
1279 // Iterate over the sequence aSeq
1280 Standard_Integer aNbGroups = aSeq->Length();
1281 Standard_Integer i = 2;
1282 for (; i <= aNbGroups; i++) {
1283 Handle(Standard_Transient) anItem = aSeq->Value(i);
1284 if (anItem.IsNull()) continue;
1285 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
1286 if (aGroup.IsNull()) continue;
1287 //Make a Python command
1288 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
1289 aListRes += anEntry + ", ";
1292 aListRes.Trunc(aListRes.Length() - 2);
1294 //Make a Python command
1295 GEOM::TPythonDump(aFunction) << "[" << aShape << ", " << aListRes.ToCString() << "] = geompy.MakePipeTShape("
1296 << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", "
1297 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3 << ")";
1300 // Get the groups: END
1304 //Make a Python command
1305 GEOM::TPythonDump(aFunction) << "[" << aShape << "] = geompy.MakePipeTShape(" << theR1 << ", " << theW1 << ", "
1306 << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theHexMesh << ", " << theP1
1307 << ", " << theP2 << ", " << theP3 << ")";
1315 //=============================================================================
1317 * MakePipeTShapeChamfer
1318 * Create a T-shape object with specified caracteristics for the main and
1319 * the incident pipes (radius, width, half-length). A chamfer is created
1320 * on the junction of the pipes.
1321 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1322 * \param theR1 Internal radius of main pipe
1323 * \param theW1 Width of main pipe
1324 * \param theL1 Half-length of main pipe
1325 * \param theR2 Internal radius of incident pipe (R2 < R1)
1326 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1327 * \param theL2 Half-length of incident pipe
1328 * \param theH Height of chamfer.
1329 * \param theW Width of chamfer.
1330 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1331 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1333 //=============================================================================
1334 Handle(TColStd_HSequenceOfTransient)
1335 GEOMImpl_IAdvancedOperations::MakePipeTShapeChamfer(double theR1, double theW1, double theL1,
1336 double theR2, double theW2, double theL2,
1337 double theH, double theW,
1342 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1343 //Add a new shape function with parameters
1344 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
1345 if (aFunction.IsNull()) return NULL;
1347 //Check if the function is set correctly
1348 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
1350 GEOMImpl_IPipeTShape aData(aFunction);
1360 aData.SetHexMesh(theHexMesh);
1362 //Compute the resulting value
1364 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1367 if (!GetSolver()->ComputeFunction(aFunction)) {
1368 SetErrorCode("TShape driver failed");
1371 } catch (Standard_Failure) {
1372 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1373 SetErrorCode(aFail->GetMessageString());
1378 TopoDS_Shape aShapeShape = aShape->GetValue();
1379 TopTools_IndexedMapOfShape anEdgesIndices;
1380 TopExp::MapShapes(aShapeShape, anEdgesIndices);
1381 // Common edges on external cylinders
1382 Handle(GEOM_Object) box_e;
1384 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
1387 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
1389 box_e->GetLastFunction()->SetDescription("");
1390 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
1391 box_e->GetLastFunction()->SetDescription("");
1393 Handle(TColStd_HSequenceOfInteger) edges_e = myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1394 box_e->GetLastFunction()->SetDescription("");
1396 if (edges_e.IsNull() || edges_e->Length() == 0) {
1397 SetErrorCode("External edges not found");
1400 int nbEdgesInChamfer = 0;
1401 std::list<int> theEdges;
1402 for (int i=1; i<=edges_e->Length();i++) {
1403 int edgeID = edges_e->Value(i);
1404 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
1405 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
1409 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
1410 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
1411 nbEdgesInChamfer ++;
1412 theEdges.push_back(edgeID);
1416 if (theHexMesh && nbEdgesInChamfer == 1)
1419 Handle(GEOM_Object) aChamfer;
1421 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
1423 catch (Standard_Failure) {
1424 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1425 SetErrorCode(aFail->GetMessageString());
1428 if (aChamfer.IsNull()) {
1429 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
1432 aChamfer->GetLastFunction()->SetDescription("");
1434 TopoDS_Shape aChamferShape = aChamfer->GetValue();
1435 aFunction->SetValue(aChamferShape);
1438 // bool doMesh = false;
1441 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false)) {
1442 MESSAGE("PipeTShape partition failed");
1446 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2)) {
1447 MESSAGE("PipeTShape mirrors and glue failed");
1453 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1454 aSeq->Append(aShape);
1459 // Get the groups: BEGIN
1461 // if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, gp_Trsf())) {
1462 // //Make a Python command
1463 // GEOM::TPythonDump(aFunction) << "[" << aShape << "] = geompy.MakePipeTShapeChamfer(" << theR1 << ", " << theW1
1464 // << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theH << ", " << theW
1465 // << ", " << theHexMesh << ")";
1468 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, gp_Trsf()))
1471 TCollection_AsciiString aListRes, anEntry;
1472 // Iterate over the sequence aSeq
1473 Standard_Integer aNbGroups = aSeq->Length();
1474 Standard_Integer i = 2;
1475 for (; i <= aNbGroups; i++) {
1476 Handle(Standard_Transient) anItem = aSeq->Value(i);
1477 if (anItem.IsNull()) continue;
1478 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
1479 if (aGroup.IsNull()) continue;
1480 //Make a Python command
1481 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
1482 aListRes += anEntry + ", ";
1485 aListRes.Trunc(aListRes.Length() - 2);
1487 //Make a Python command
1488 GEOM::TPythonDump(aFunction) << "[" << aShape << ", " << aListRes.ToCString()
1489 << "] = geompy.MakePipeTShapeChamfer(" << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2
1490 << ", " << theW2 << ", " << theL2 << ", " << theH << ", " << theW << ", " << theHexMesh << ")";
1494 // Get the groups: END
1497 //Make a Python command
1498 GEOM::TPythonDump(aFunction) << "[" << aShape << "] = geompy.MakePipeTShapeChamfer(" << theR1 << ", " << theW1
1499 << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theH << ", " << theW
1500 << ", " << theHexMesh << ")";
1508 //=============================================================================
1510 * MakePipeTShapeChamferWithPosition
1511 * Create a T-shape object with specified caracteristics for the main and
1512 * the incident pipes (radius, width, half-length). A chamfer is created
1513 * on the junction of the pipes.
1514 * The extremities of the main pipe are located on junctions points P1 and P2.
1515 * The extremity of the incident pipe is located on junction point P3.
1516 * \param theR1 Internal radius of main pipe
1517 * \param theW1 Width of main pipe
1518 * \param theL1 Half-length of main pipe
1519 * \param theR2 Internal radius of incident pipe (R2 < R1)
1520 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1521 * \param theL2 Half-length of incident pipe
1522 * \param theH Height of chamfer.
1523 * \param theW Width of chamfer.
1524 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1525 * \param theP1 1st junction point of main pipe
1526 * \param theP2 2nd junction point of main pipe
1527 * \param theP3 Junction point of incident pipe
1528 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1530 //=============================================================================
1531 Handle(TColStd_HSequenceOfTransient)
1532 GEOMImpl_IAdvancedOperations::MakePipeTShapeChamferWithPosition(double theR1, double theW1, double theL1,
1533 double theR2, double theW2, double theL2,
1534 double theH, double theW,
1536 Handle(GEOM_Object) theP1,
1537 Handle(GEOM_Object) theP2,
1538 Handle(GEOM_Object) theP3)
1542 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1543 //Add a new shape function with parameters
1544 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
1545 if (aFunction.IsNull()) return NULL;
1547 //Check if the function is set correctly
1548 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
1550 // Check new position
1551 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
1555 GEOMImpl_IPipeTShape aData(aFunction);
1565 aData.SetHexMesh(theHexMesh);
1567 //Compute the resulting value
1569 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1572 if (!GetSolver()->ComputeFunction(aFunction)) {
1573 SetErrorCode("TShape driver failed");
1576 } catch (Standard_Failure) {
1577 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1578 SetErrorCode(aFail->GetMessageString());
1583 TopoDS_Shape aShapeShape = aShape->GetValue();
1584 TopTools_IndexedMapOfShape anEdgesIndices;
1585 TopExp::MapShapes(aShapeShape, anEdgesIndices);
1586 // Common edges on external cylinders
1587 Handle(GEOM_Object) box_e;
1589 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
1592 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
1594 box_e->GetLastFunction()->SetDescription("");
1595 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
1596 box_e->GetLastFunction()->SetDescription("");
1598 Handle(TColStd_HSequenceOfInteger) edges_e = myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1599 box_e->GetLastFunction()->SetDescription("");
1601 if (edges_e.IsNull() || edges_e->Length() == 0) {
1602 SetErrorCode("External edges not found");
1605 int nbEdgesInChamfer = 0;
1606 std::list<int> theEdges;
1607 for (int i=1; i<=edges_e->Length();i++) {
1608 int edgeID = edges_e->Value(i);
1609 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
1610 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
1612 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
1613 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
1614 nbEdgesInChamfer ++;
1615 theEdges.push_back(edgeID);
1619 if (theHexMesh && nbEdgesInChamfer == 1)
1622 Handle(GEOM_Object) aChamfer;
1624 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
1626 catch (Standard_Failure) {
1627 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1628 SetErrorCode(aFail->GetMessageString());
1631 if (aChamfer.IsNull()) {
1632 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
1635 aChamfer->GetLastFunction()->SetDescription("");
1637 TopoDS_Shape aChamferShape = aChamfer->GetValue();
1638 aFunction->SetValue(aChamferShape);
1642 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
1644 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1648 TopoDS_Shape Te = aShape->GetValue();
1651 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
1652 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
1653 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
1654 aFunction->SetValue(aTrsf_Shape);
1655 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1656 aSeq->Append(aShape);
1659 * Get the groups: BEGIN
1661 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, aTrsf))
1664 TCollection_AsciiString aListRes, anEntry;
1665 // Iterate over the sequence aSeq
1666 Standard_Integer aNbGroups = aSeq->Length();
1667 Standard_Integer i = 2;
1668 for (; i <= aNbGroups; i++) {
1669 Handle(Standard_Transient) anItem = aSeq->Value(i);
1670 if (anItem.IsNull()) continue;
1671 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
1672 if (aGroup.IsNull()) continue;
1673 //Make a Python command
1674 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
1675 aListRes += anEntry + ", ";
1678 aListRes.Trunc(aListRes.Length() - 2);
1680 //Make a Python command
1681 GEOM::TPythonDump(aFunction) << "[" << aShape << ", " << aListRes.ToCString()
1682 << "] = geompy.MakePipeTShapeChamfer(" << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2
1683 << ", " << theW2 << ", " << theL2 << ", " << theH << ", " << theW << ", " << theHexMesh << ", "
1684 << theP1 << ", " << theP2 << ", " << theP3 << ")";
1687 * Get the groups: END
1690 //Make a Python command
1691 GEOM::TPythonDump(aFunction) << "[" << aShape << "] = geompy.MakePipeTShapeChamfer(" << theR1 << ", " << theW1
1692 << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theH << ", " << theW
1693 << ", " << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3 << ")";
1701 //=============================================================================
1703 * MakePipeTShapeFillet
1704 * Create a T-shape object with specified caracteristics for the main and
1705 * the incident pipes (radius, width, half-length). A fillet is created
1706 * on the junction of the pipes.
1707 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1708 * \param theR1 Internal radius of main pipe
1709 * \param theW1 Width of main pipe
1710 * \param theL1 Half-length of main pipe
1711 * \param theR2 Internal radius of incident pipe (R2 < R1)
1712 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1713 * \param theL2 Half-length of incident pipe
1714 * \param theRF Radius of curvature of fillet.
1715 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1716 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1718 //=============================================================================
1719 Handle(TColStd_HSequenceOfTransient)
1720 GEOMImpl_IAdvancedOperations::MakePipeTShapeFillet(double theR1, double theW1, double theL1,
1721 double theR2, double theW2, double theL2,
1722 double theRF, bool theHexMesh)
1726 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1727 //Add a new shape function with parameters
1728 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
1729 if (aFunction.IsNull()) return NULL;
1731 //Check if the function is set correctly
1732 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
1734 GEOMImpl_IPipeTShape aData(aFunction);
1743 aData.SetHexMesh(theHexMesh);
1745 //Compute the resulting value
1747 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1750 if (!GetSolver()->ComputeFunction(aFunction)) {
1751 SetErrorCode("TShape driver failed");
1754 } catch (Standard_Failure) {
1755 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1756 SetErrorCode(aFail->GetMessageString());
1761 TopoDS_Shape aShapeShape = aShape->GetValue();
1762 TopTools_IndexedMapOfShape anEdgesIndices;
1763 TopExp::MapShapes(aShapeShape, anEdgesIndices);
1764 // Common edges on external cylinders
1765 Handle(GEOM_Object) box_e;
1767 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
1770 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
1772 box_e->GetLastFunction()->SetDescription("");
1773 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
1774 box_e->GetLastFunction()->SetDescription("");
1776 Handle(TColStd_HSequenceOfInteger) edges_e = myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1777 box_e->GetLastFunction()->SetDescription("");
1779 if (edges_e.IsNull() || edges_e->Length() == 0) {
1780 SetErrorCode("External edges not found");
1783 int nbEdgesInFillet = 0;
1784 std::list<int> theEdges;
1785 for (int i=1; i<=edges_e->Length();i++) {
1786 int edgeID = edges_e->Value(i);
1787 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
1788 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
1790 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
1791 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
1793 theEdges.push_back(edgeID);
1797 if (theHexMesh && nbEdgesInFillet == 1)
1801 Handle(GEOM_Object) aFillet;
1803 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
1805 catch (Standard_Failure) {
1806 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1807 SetErrorCode(aFail->GetMessageString());
1810 if (aFillet.IsNull()) {
1811 SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
1814 aFillet->GetLastFunction()->SetDescription("");
1816 TopoDS_Shape aFilletShape = aFillet->GetValue();
1817 aFunction->SetValue(aFilletShape);
1821 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
1823 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1827 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1828 aSeq->Append(aShape);
1831 * Get the groups: BEGIN
1833 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, gp_Trsf()))
1836 TCollection_AsciiString aListRes, anEntry;
1837 // Iterate over the sequence aSeq
1838 Standard_Integer aNbGroups = aSeq->Length();
1839 Standard_Integer i = 2;
1840 for (; i <= aNbGroups; i++) {
1841 Handle(Standard_Transient) anItem = aSeq->Value(i);
1842 if (anItem.IsNull()) continue;
1843 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
1844 if (aGroup.IsNull()) continue;
1845 //Make a Python command
1846 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
1847 aListRes += anEntry + ", ";
1850 aListRes.Trunc(aListRes.Length() - 2);
1852 //Make a Python command
1853 GEOM::TPythonDump(aFunction) << "[" << aShape << ", " << aListRes.ToCString()
1854 << "] = geompy.MakePipeTShapeFillet(" << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2
1855 << ", " << theW2 << ", " << theL2 << ", " << theRF << ", " << theHexMesh << ")";
1858 * Get the groups: END
1861 //Make a Python command
1862 GEOM::TPythonDump(aFunction) << "[" << aShape << "] = geompy.MakePipeTShapeFillet(" << theR1 << ", " << theW1
1863 << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theRF << ", "
1864 << theHexMesh << ")";
1874 //=============================================================================
1876 * MakePipeTShapeFilletWithPosition
1877 * Create a T-shape object with specified caracteristics for the main and
1878 * the incident pipes (radius, width, half-length). A fillet is created
1879 * on the junction of the pipes.
1880 * The extremities of the main pipe are located on junctions points P1 and P2.
1881 * The extremity of the incident pipe is located on junction point P3.
1882 * \param theR1 Internal radius of main pipe
1883 * \param theW1 Width of main pipe
1884 * \param theL1 Half-length of main pipe
1885 * \param theR2 Internal radius of incident pipe (R2 < R1)
1886 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1887 * \param theL2 Half-length of incident pipe
1888 * \param theRF Radius of curvature of fillet
1889 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1890 * \param theP1 1st junction point of main pipe
1891 * \param theP2 2nd junction point of main pipe
1892 * \param theP3 Junction point of incident pipe
1893 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1895 //=============================================================================
1896 Handle(TColStd_HSequenceOfTransient)
1897 GEOMImpl_IAdvancedOperations::MakePipeTShapeFilletWithPosition(double theR1, double theW1, double theL1,
1898 double theR2, double theW2, double theL2,
1899 double theRF, bool theHexMesh,
1900 Handle(GEOM_Object) theP1,
1901 Handle(GEOM_Object) theP2,
1902 Handle(GEOM_Object) theP3)
1906 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1907 //Add a new shape function with parameters
1908 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
1909 if (aFunction.IsNull()) return NULL;
1911 //Check if the function is set correctly
1912 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
1914 // Check new position
1915 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
1919 GEOMImpl_IPipeTShape aData(aFunction);
1928 aData.SetHexMesh(theHexMesh);
1930 //Compute the resulting value
1932 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1935 if (!GetSolver()->ComputeFunction(aFunction)) {
1936 SetErrorCode("TShape driver failed");
1939 } catch (Standard_Failure) {
1940 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1941 SetErrorCode(aFail->GetMessageString());
1946 TopoDS_Shape aShapeShape = aShape->GetValue();
1947 TopTools_IndexedMapOfShape anEdgesIndices;
1948 TopExp::MapShapes(aShapeShape, anEdgesIndices);
1949 // Common edges on external cylinders
1950 Handle(GEOM_Object) box_e;
1952 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
1955 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
1957 box_e->GetLastFunction()->SetDescription("");
1958 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
1959 box_e->GetLastFunction()->SetDescription("");
1961 Handle(TColStd_HSequenceOfInteger) edges_e = myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1962 box_e->GetLastFunction()->SetDescription("");
1964 if (edges_e.IsNull() || edges_e->Length() == 0) {
1965 SetErrorCode("External edges not found");
1968 int nbEdgesInFillet = 0;
1969 std::list<int> theEdges;
1970 for (int i=1; i<=edges_e->Length();i++) {
1971 int edgeID = edges_e->Value(i);
1972 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
1973 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
1975 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
1976 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
1978 theEdges.push_back(edgeID);
1982 if (theHexMesh && nbEdgesInFillet == 1)
1986 Handle(GEOM_Object) aFillet;
1988 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
1990 catch (Standard_Failure) {
1991 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1992 SetErrorCode(aFail->GetMessageString());
1995 if (aFillet.IsNull()) {
1996 SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
1999 aFillet->GetLastFunction()->SetDescription("");
2001 TopoDS_Shape aFilletShape = aFillet->GetValue();
2002 aFunction->SetValue(aFilletShape);
2006 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2008 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2012 TopoDS_Shape Te = aShape->GetValue();
2015 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2016 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
2017 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2018 aFunction->SetValue(aTrsf_Shape);
2019 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2020 aSeq->Append(aShape);
2023 * Get the groups: BEGIN
2025 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2, aSeq, aTrsf))
2028 TCollection_AsciiString aListRes, anEntry;
2029 // Iterate over the sequence aSeq
2030 Standard_Integer aNbGroups = aSeq->Length();
2031 Standard_Integer i = 2;
2032 for (; i <= aNbGroups; i++) {
2033 Handle(Standard_Transient) anItem = aSeq->Value(i);
2034 if (anItem.IsNull()) continue;
2035 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2036 if (aGroup.IsNull()) continue;
2037 //Make a Python command
2038 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2039 aListRes += anEntry + ", ";
2042 aListRes.Trunc(aListRes.Length() - 2);
2044 //Make a Python command
2045 GEOM::TPythonDump(aFunction) << "[" << aShape << ", " << aListRes.ToCString()
2046 << "] = geompy.MakePipeTShapeFillet(" << theR1 << ", " << theW1 << ", " << theL1 << ", " << theR2
2047 << ", " << theW2 << ", " << theL2 << ", " << theRF << ", " << theHexMesh << ", " << theP1 << ", "
2048 << theP2 << ", " << theP3 << ")";
2051 * Get the groups: END
2054 //Make a Python command
2055 GEOM::TPythonDump(aFunction) << "[" << aShape << "] = geompy.MakePipeTShapeFillet(" << theR1 << ", " << theW1
2056 << ", " << theL1 << ", " << theR2 << ", " << theW2 << ", " << theL2 << ", " << theRF << ", "
2057 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3 << ")";
2065 /*@@ insert new functions before this line @@ do not remove this line @@ do not remove this line @@*/