1 // Copyright (C) 2007-2014 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, or (at your option) any later version.
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
19 // File : AdvancedEngine_IOperations.cxx
20 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
22 #include "AdvancedEngine_IOperations.hxx"
23 #include "AdvancedEngine_PipeTShapeDriver.hxx"
24 #include "AdvancedEngine_IPipeTShape.hxx"
25 #include "AdvancedEngine_DividedDiskDriver.hxx"
26 #include "AdvancedEngine_IDividedDisk.hxx"
27 #include "AdvancedEngine_SmoothingSurfaceDriver.hxx"
28 #include "AdvancedEngine_ISmoothingSurface.hxx"
30 #include <Basics_OCCTVersion.hxx>
32 #include <utilities.h>
34 #include <Utils_ExceptHandlers.hxx>
36 #include "GEOM_Function.hxx"
37 #include "GEOM_PythonDump.hxx"
38 #include "GEOMUtils.hxx"
39 #include "GEOMAlgo_Splitter.hxx"
40 #include "GEOMAlgo_FinderShapeOn1.hxx"
42 #include "GEOMImpl_Gen.hxx"
43 #include "GEOMImpl_Types.hxx"
45 #include "GEOMImpl_IBasicOperations.hxx"
46 #include "GEOMImpl_IBooleanOperations.hxx"
47 #include "GEOMImpl_IShapesOperations.hxx"
48 #include "GEOMImpl_ITransformOperations.hxx"
49 #include "GEOMImpl_IBlocksOperations.hxx"
50 #include "GEOMImpl_I3DPrimOperations.hxx"
51 #include "GEOMImpl_ILocalOperations.hxx"
52 #include "GEOMImpl_IHealingOperations.hxx"
53 #include "GEOMImpl_IGroupOperations.hxx"
54 #include "GEOMImpl_GlueDriver.hxx"
56 #include <TDF_Tool.hxx>
57 #include <TFunction_DriverTable.hxx>
58 #include <TFunction_Driver.hxx>
59 #include <TFunction_Logbook.hxx>
60 #include <TNaming_CopyShape.hxx>
63 #include <TopExp_Explorer.hxx>
65 #include <TopoDS_Vertex.hxx>
66 #include <TopTools_IndexedMapOfShape.hxx>
67 #include <TopTools_ListIteratorOfListOfShape.hxx>
68 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
70 #include <BRep_Builder.hxx>
71 #include <BRep_Tool.hxx>
73 #include <BRepAdaptor_Surface.hxx>
74 #include <BRepAlgoAPI_Cut.hxx>
75 #include <BRepAlgoAPI_Fuse.hxx>
76 #include <BRepBuilderAPI_MakeFace.hxx>
77 #include <BRepBuilderAPI_MakeVertex.hxx>
78 #include <BRepBuilderAPI_Transform.hxx>
79 #include <BRepPrimAPI_MakeCone.hxx>
80 #include <BRepPrimAPI_MakeCylinder.hxx>
86 #include <GC_MakeConicalSurface.hxx>
87 #include <Geom_CylindricalSurface.hxx>
89 #include <ShapeAnalysis_Edge.hxx>
93 #include "AdvancedEngine_Types.hxx"
95 #include <Standard_Stream.hxx>
96 #include <Standard_Failure.hxx>
97 #include <StdFail_NotDone.hxx>
98 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
100 #define HALF_LENGTH_MAIN_PIPE "Main pipe half length" //"Tuyau principal - demi longueur"
101 #define HALF_LENGTH_INCIDENT_PIPE "Incident pipe half length" //"Tuyau incident - demi longueur"
102 #define CIRCULAR_QUARTER_PIPE "Circular quarter of pipe" //"Circulaire - quart de tuyau"
103 #define THICKNESS "Thickness" //"Epaisseur"
104 #define FLANGE "Flange" // "Collerette"
105 #define CHAMFER_OR_FILLET "Chamfer or fillet" //"Chanfrein ou Raccord"
106 #define JUNCTION_FACE_1 "Junction 1" //"Face de jonction 1"
107 #define JUNCTION_FACE_2 "Junction 2" //"Face de jonction 2"
108 #define JUNCTION_FACE_3 "Junction 3" //"Face de jonction 3"
110 #define FIND_GROUPS_BY_POINTS 1
112 //=============================================================================
116 //=============================================================================
117 AdvancedEngine_IOperations::AdvancedEngine_IOperations(GEOM_Engine* theEngine, int theDocID) :
118 GEOM_IOperations(theEngine, theDocID)
120 MESSAGE("AdvancedEngine_IOperations::AdvancedEngine_IOperations");
121 myBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
122 myBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
123 myShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
124 myTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
125 myBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
126 my3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
127 myLocalOperations = new GEOMImpl_ILocalOperations(GetEngine(), GetDocID());
128 myHealingOperations = new GEOMImpl_IHealingOperations(GetEngine(), GetDocID());
129 myGroupOperations = new GEOMImpl_IGroupOperations(GetEngine(), GetDocID());
132 //=============================================================================
136 //=============================================================================
137 AdvancedEngine_IOperations::~AdvancedEngine_IOperations()
139 MESSAGE("AdvancedEngine_IOperations::~AdvancedEngine_IOperations");
140 delete myBasicOperations;
141 delete myBooleanOperations;
142 delete myShapesOperations;
143 delete myTransformOperations;
144 delete myBlocksOperations;
145 delete my3DPrimOperations;
146 delete myLocalOperations;
147 delete myHealingOperations;
148 delete myGroupOperations;
151 //=============================================================================
155 //=============================================================================
156 gp_Trsf AdvancedEngine_IOperations::GetPositionTrsf(double theL1, double theL2,
157 Handle(GEOM_Object) theP1,
158 Handle(GEOM_Object) theP2,
159 Handle(GEOM_Object) theP3)
161 // Old Local Coordinates System oldLCS
163 gp_Pnt P1(-theL1, 0, 0);
164 gp_Pnt P2(theL1, 0, 0);
165 gp_Pnt P3(0, 0, theL2);
167 gp_Dir oldX(gp_Vec(P1, P2));
168 gp_Dir oldZ(gp_Vec(P0, P3));
169 gp_Ax3 oldLCS(P0, oldZ, oldX);
171 // New Local Coordinates System newLCS
172 double LocX, LocY, LocZ;
173 gp_Pnt newP1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
174 gp_Pnt newP2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
175 gp_Pnt newP3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
176 LocX = (newP1.X() + newP2.X()) / 2.;
177 LocY = (newP1.Y() + newP2.Y()) / 2.;
178 LocZ = (newP1.Z() + newP2.Z()) / 2.;
179 gp_Pnt newO(LocX, LocY, LocZ);
181 gp_Dir newX(gp_Vec(newP1, newP2)); // P1P2 Vector
182 gp_Dir newZ(gp_Vec(newO, newP3)); // OP3 Vector
183 gp_Ax3 newLCS = gp_Ax3(newO, newZ, newX);
186 aTrsf.SetDisplacement(oldLCS, newLCS);
191 //=============================================================================
193 * CheckCompatiblePosition
196 //=============================================================================
197 bool AdvancedEngine_IOperations::CheckCompatiblePosition(double& theL1, double& theL2,
198 Handle(GEOM_Object) theP1,
199 Handle(GEOM_Object) theP2,
200 Handle(GEOM_Object) theP3,
204 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
205 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
206 gp_Pnt P3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
208 double d12 = P1.Distance(P2);
209 double d13 = P1.Distance(P3);
210 double d23 = P2.Distance(P3);
211 // double d2 = newO.Distance(P3);
213 if (Abs(d12) <= Precision::Confusion()) {
214 SetErrorCode("Junctions points P1 and P2 are identical");
217 if (Abs(d13) <= Precision::Confusion()) {
218 SetErrorCode("Junctions points P1 and P3 are identical");
221 if (Abs(d23) <= Precision::Confusion()) {
222 SetErrorCode("Junctions points P2 and P3 are identical");
227 double newL1 = 0.5 * d12;
228 double newL2 = sqrt(pow(d13,2)-pow(newL1,2));
230 // theL1*(1-theTolerance) <= newL1 <= theL1*(1+theTolerance)
232 if (fabs(newL1 - theL1) > Precision::Approximation()) {
233 if ( (newL1 * (1 - theTolerance) -theL1 <= Precision::Approximation()) &&
234 (newL1 * (1 + theTolerance) -theL1 >= Precision::Approximation()) ) {
235 // std::cerr << "theL1 = newL1" << std::endl;
239 SetErrorCode("Dimension for main pipe (L1) is incompatible with new position");
245 // theL2*(1-theTolerance) <= newL2 <= theL2*(1+theTolerance)
247 if (fabs(newL2 - theL2) > Precision::Approximation()) {
248 if ( (newL2 * (1 - theTolerance) -theL2 <= Precision::Approximation()) &&
249 (newL2 * (1 + theTolerance) -theL2 >= Precision::Approximation()) ) {
253 SetErrorCode("Dimension for incident pipe (L2) is incompatible with new position");
263 //=============================================================================
265 * Generate the propagation groups of a Pipe T-Shape used for hexa mesh
267 //=============================================================================
268 bool AdvancedEngine_IOperations::MakeGroups(Handle(GEOM_Object) theShape, int shapeType,
269 double theR1, double theW1, double theL1,
270 double theR2, double theW2, double theL2,
271 double theH, double theW, double theRF,
272 Handle(TColStd_HSequenceOfTransient) theSeq,
277 if (theShape.IsNull()) return false;
279 TopoDS_Shape aShape = theShape->GetValue();
280 if (aShape.IsNull()) {
281 SetErrorCode("Shape is not defined");
285 gp_Trsf aTrsfInv = aTrsf.Inverted();
287 // int expectedGroups = 0;
288 // if (shapeType == TSHAPE_BASIC)
289 // if (Abs(theR2+theW2-theR1-theW1) <= Precision::Approximation())
290 // expectedGroups = 10;
292 // expectedGroups = 11;
293 // else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET)
294 // expectedGroups = 12;
296 double aR1Ext = theR1 + theW1;
297 double aR2Ext = theR2 + theW2;
299 /////////////////////////
300 //// Groups of Faces ////
301 /////////////////////////
304 // Comment the following lines when GetInPlace bug is solved
306 // Workaround of GetInPlace bug
307 // Create a bounding box that fits the shape
308 Handle(GEOM_Object) aBox = my3DPrimOperations->MakeBoxDXDYDZ(2*theL1, 2*aR1Ext, aR1Ext+theL2);
309 aBox->GetLastFunction()->SetDescription("");
310 myTransformOperations->TranslateDXDYDZ(aBox, -theL1, -aR1Ext, -aR1Ext);
311 aBox->GetLastFunction()->SetDescription("");
312 // Apply transformation to box
313 BRepBuilderAPI_Transform aTransformationBox(aBox->GetValue(), aTrsf, Standard_False);
314 TopoDS_Shape aBoxShapeTrsf = aTransformationBox.Shape();
315 aBox->GetLastFunction()->SetValue(aBoxShapeTrsf);
317 // Get the shell of the box
318 Handle(GEOM_Object) aShell = Handle(GEOM_Object)::DownCast
319 (myShapesOperations->MakeExplode(aBox, TopAbs_SHELL, true)->Value(1));
320 aBox->GetLastFunction()->SetDescription("");
321 aShell->GetLastFunction()->SetDescription("");
322 // Get the common shapes between shell and shape
323 Handle(GEOM_Object) aCommonCompound = myBooleanOperations->MakeBoolean
324 (theShape, aShell, 1, Standard_False); // MakeCommon
325 if (aCommonCompound.IsNull()) {
326 SetErrorCode(myBooleanOperations->GetErrorCode());
329 aCommonCompound->GetLastFunction()->SetDescription("");
330 // Explode the faces of common shapes => 3 faces
331 Handle(TColStd_HSequenceOfTransient) aCommonFaces =
332 myShapesOperations->MakeExplode(aCommonCompound, TopAbs_FACE, true);
333 aCommonCompound->GetLastFunction()->SetDescription("");
334 std::list<Handle(GEOM_Object)> aCompoundOfFacesList;
336 for (int i=0 ; i<= aCommonFaces->Length()-4 ; i+=4) {
337 std::list<Handle(GEOM_Object)> aFacesList;
338 for (int j = 1 ; j <= 4 ; j++) {
339 Handle(GEOM_Object) aFace = Handle(GEOM_Object)::DownCast(aCommonFaces->Value(i+j)); // Junction faces
340 if (!aFace.IsNull()) {
341 aFace->GetLastFunction()->SetDescription("");
342 aFacesList.push_back(aFace);
345 Handle(GEOM_Object) aCompoundOfFaces = myShapesOperations->MakeCompound(aFacesList);
346 if (!aCompoundOfFaces.IsNull()) {
347 aCompoundOfFaces->GetLastFunction()->SetDescription("");
348 aCompoundOfFacesList.push_back(aCompoundOfFaces);
352 if (aCompoundOfFacesList.size() == 3) {
353 Handle(GEOM_Object) aPln1 = aCompoundOfFacesList.front();
354 aCompoundOfFacesList.pop_front();
355 Handle(GEOM_Object) aPln2 = aCompoundOfFacesList.front();
356 aCompoundOfFacesList.pop_front();
357 Handle(GEOM_Object) aPln3 = aCompoundOfFacesList.front();
358 aCompoundOfFacesList.pop_front();
363 // Uncomment the following lines when GetInPlace bug is solved
365 // Handle(GEOM_Object) aP1 = myBasicOperations->MakePointXYZ(-theL1, 0, 0);
366 // Handle(GEOM_Object) aP2 = myBasicOperations->MakePointXYZ(-0, 0, theL2);
367 // Handle(GEOM_Object) aP3 = myBasicOperations->MakePointXYZ(theL1, 0, 0);
368 // aP1->GetLastFunction()->SetDescription("");
369 // aP2->GetLastFunction()->SetDescription("");
370 // aP3->GetLastFunction()->SetDescription("");
371 // Handle(GEOM_Object) aV1 = myBasicOperations->MakeVectorDXDYDZ(-1, 0, 0);
372 // Handle(GEOM_Object) aV2 = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
373 // Handle(GEOM_Object) aV3 = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
374 // aV1->GetLastFunction()->SetDescription("");
375 // aV2->GetLastFunction()->SetDescription("");
376 // aV3->GetLastFunction()->SetDescription("");
377 // Handle(GEOM_Object) aPln1 = myBasicOperations->MakePlanePntVec(aP1, aV1, 2*(aR1Ext+theL2));
378 // Handle(GEOM_Object) aPln2 = myBasicOperations->MakePlanePntVec(aP2, aV2, 2*(aR2Ext));
379 // Handle(GEOM_Object) aPln3 = myBasicOperations->MakePlanePntVec(aP3, aV3, 2*(aR1Ext+theL2));
380 // aPln1->GetLastFunction()->SetDescription("");
381 // aPln2->GetLastFunction()->SetDescription("");
382 // aPln3->GetLastFunction()->SetDescription("");
384 // BRepBuilderAPI_Transform aTransformation1(aPln1->GetValue(), aTrsf, Standard_False);
385 // TopoDS_Shape aTrsf_Shape1 = aTransformation1.Shape();
386 // aPln1->GetLastFunction()->SetValue(aTrsf_Shape1);
387 // BRepBuilderAPI_Transform aTransformation2(aPln2->GetValue(), aTrsf, Standard_False);
388 // TopoDS_Shape aTrsf_Shape2 = aTransformation2.Shape();
389 // aPln2->GetLastFunction()->SetValue(aTrsf_Shape2);
390 // BRepBuilderAPI_Transform aTransformation3(aPln3->GetValue(), aTrsf, Standard_False);
391 // TopoDS_Shape aTrsf_Shape3 = aTransformation3.Shape();
392 // aPln3->GetLastFunction()->SetValue(aTrsf_Shape3);
396 Handle(GEOM_Object) junctionFaces1 = myShapesOperations->GetInPlace(theShape, aPln1);
397 if (junctionFaces1.IsNull())
398 junctionFaces1 = myShapesOperations->GetShapesOnShapeAsCompound
399 (aPln1, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
400 if (!junctionFaces1.IsNull()) {
401 junctionFaces1->GetLastFunction()->SetDescription("");
402 junctionFaces1->SetName("JUNCTION_FACE_1");
403 theSeq->Append(junctionFaces1);
406 SetErrorCode("Junction face 1 not found");
407 // theSeq->Append(aPln1);
410 Handle(GEOM_Object) junctionFaces2 = myShapesOperations->GetInPlace(theShape, aPln2);
411 if (junctionFaces2.IsNull())
412 junctionFaces2 = myShapesOperations->GetShapesOnShapeAsCompound
413 (aPln2, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
414 if (!junctionFaces2.IsNull()) {
415 junctionFaces2->GetLastFunction()->SetDescription("");
416 junctionFaces2->SetName("JUNCTION_FACE_2");
417 theSeq->Append(junctionFaces2);
420 SetErrorCode("Junction face 2 not found");
421 // theSeq->Append(aPln2);
424 Handle(GEOM_Object) junctionFaces3 = myShapesOperations->GetInPlace(theShape, aPln3);
425 if (junctionFaces3.IsNull())
426 junctionFaces3 = myShapesOperations->GetShapesOnShapeAsCompound
427 (aPln3, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
428 if (!junctionFaces3.IsNull()) {
429 junctionFaces3->GetLastFunction()->SetDescription("");
430 junctionFaces3->SetName("JUNCTION_FACE_3");
431 theSeq->Append(junctionFaces3);
434 SetErrorCode("Junction face 3 not found");
435 // theSeq->Append(aPln3);
438 // Comment the following lines when GetInPlace bug is solved
443 /////////////////////////
444 //// Groups of Edges ////
445 /////////////////////////
446 // Result of propagate
448 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
450 TCollection_AsciiString theDesc = aFunction->GetDescription();
451 Handle(TColStd_HSequenceOfTransient) aSeqPropagate = myBlocksOperations->Propagate(theShape);
452 if (aSeqPropagate.IsNull() || aSeqPropagate->Length() == 0) {
453 SetErrorCode("Propagation groups not found");
456 Standard_Integer aNbGroups = aSeqPropagate->Length();
457 // Recover previous description to get rid of Propagate dump
458 aFunction->SetDescription(theDesc);
460 #ifdef FIND_GROUPS_BY_POINTS
461 // BEGIN: new groups search
468 // g / ''..| | |..'' \
470 // .---.--'.. | | | ..'--.---.
471 // |a \ '''...........''' / |
472 // |-------\------' | '------/-------.
477 // ._________________|_________________.
483 // |-----------------|-----------------|
485 // '-----------------'-----------------'
488 // "Thickness" group (a)
489 gp_Pnt aPntA (-theL1, 0, theR1 + theW1/2.);
490 aPntA.Transform(aTrsf);
491 BRepBuilderAPI_MakeVertex mkVertexA (aPntA);
492 TopoDS_Vertex aVertA = TopoDS::Vertex(mkVertexA.Shape());
493 TopoDS_Shape anEdgeA = GEOMUtils::GetEdgeNearPoint(aShape, aVertA);
495 // "Circular quarter of pipe" group (b)
496 gp_Pnt aPntB (-theL1, -aR1Ext * sin(M_PI/4.), -aR1Ext * sin(M_PI/4.));
497 aPntB.Transform(aTrsf);
498 BRepBuilderAPI_MakeVertex mkVertexB (aPntB);
499 TopoDS_Vertex aVertB = TopoDS::Vertex(mkVertexB.Shape());
500 TopoDS_Shape anEdgeB = GEOMUtils::GetEdgeNearPoint(aShape, aVertB);
502 // "Circular quarter of pipe" group (c)
503 gp_Pnt aPntC (-theL1, -aR1Ext * sin(M_PI/4.), aR1Ext * sin(M_PI/4.));
504 aPntC.Transform(aTrsf);
505 BRepBuilderAPI_MakeVertex mkVertexC (aPntC);
506 TopoDS_Vertex aVertC = TopoDS::Vertex(mkVertexC.Shape());
507 TopoDS_Shape anEdgeC = GEOMUtils::GetEdgeNearPoint(aShape, aVertC);
509 // "Main pipe half length" group (d)
510 gp_Pnt aPntD (-theL1/2., 0, -aR1Ext);
511 aPntD.Transform(aTrsf);
512 BRepBuilderAPI_MakeVertex mkVertexD (aPntD);
513 TopoDS_Vertex aVertD = TopoDS::Vertex(mkVertexD.Shape());
514 TopoDS_Shape anEdgeD = GEOMUtils::GetEdgeNearPoint(aShape, aVertD);
516 // "Incident pipe half length" group (e)
517 double aTol10 = Precision::Confusion() * 10.;
518 gp_Pnt aPntE (-aR2Ext, 0, theL2 - aTol10);
519 aPntE.Transform(aTrsf);
520 BRepBuilderAPI_MakeVertex mkVertexE (aPntE);
521 TopoDS_Vertex aVertE = TopoDS::Vertex(mkVertexE.Shape());
522 TopoDS_Shape anEdgeE = GEOMUtils::GetEdgeNearPoint(aShape, aVertE);
524 // "Flange" group (f)
525 double aFx = - aR2Ext - aTol10;
526 if (shapeType == TSHAPE_CHAMFER)
528 else if (shapeType == TSHAPE_FILLET)
530 gp_Pnt aPntF (aFx, 0, aR1Ext);
531 aPntF.Transform(aTrsf);
532 BRepBuilderAPI_MakeVertex mkVertexF (aPntF);
533 TopoDS_Vertex aVertF = TopoDS::Vertex(mkVertexF.Shape());
534 TopoDS_Shape anEdgeF = GEOMUtils::GetEdgeNearPoint(aShape, aVertF);
536 // "Chamfer or Fillet" group (g)
537 TopoDS_Shape anEdgeG;
538 if (shapeType == TSHAPE_CHAMFER) {
539 gp_Pnt aPntG (-aR2Ext - theW/2., 0, aR1Ext + theH/2.);
540 aPntG.Transform(aTrsf);
541 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
542 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
543 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
545 else if (shapeType == TSHAPE_FILLET) {
546 gp_Pnt aPntG (-aR2Ext - theRF/2., 0, aR1Ext + theRF/2.);
547 aPntG.Transform(aTrsf);
548 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
549 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
550 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
553 for (int i = 1 ; i <= aNbGroups; i++) {
554 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
558 TopoDS_Shape aGroupShape = aGroup->GetValue();
559 TopTools_IndexedMapOfShape anEdgesMap;
560 TopExp::MapShapes(aGroupShape, TopAbs_EDGE, anEdgesMap);
562 if (anEdgesMap.Contains(anEdgeA)) { // a
563 aGroup->SetName("THICKNESS");
564 theSeq->Append(aGroup);
566 else if (anEdgesMap.Contains(anEdgeB)) { // b
567 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
568 theSeq->Append(aGroup);
570 else if (anEdgesMap.Contains(anEdgeC)) { // c
571 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
572 theSeq->Append(aGroup);
574 else if (anEdgesMap.Contains(anEdgeD)) { // d
575 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
576 theSeq->Append(aGroup);
578 else if (anEdgesMap.Contains(anEdgeE)) { // e
579 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
580 theSeq->Append(aGroup);
582 else if (anEdgesMap.Contains(anEdgeF)) { // f
583 aGroup->SetName("FLANGE");
584 theSeq->Append(aGroup);
586 else if (shapeType == TSHAPE_CHAMFER) { // g
587 if (anEdgesMap.Contains(anEdgeG)) {
588 aGroup->SetName("CHAMFER");
589 theSeq->Append(aGroup);
592 else if (shapeType == TSHAPE_FILLET) { // g
593 if (anEdgesMap.Contains(anEdgeG)) {
594 aGroup->SetName("FILLET");
595 theSeq->Append(aGroup);
601 // END: new groups search
604 bool circularFoundAndAdded = false;
605 bool circularFound10 = false;
606 bool incidentPipeFound = false;
607 bool mainPipeFound = false;
608 bool mainPipeFoundAndAdded = false;
609 bool radialFound =false;
610 bool flangeFound = false;
611 bool flangeFoundAndAdded = false;
612 bool chamferOrFilletFound = false;
614 for (int i = 1 ; i <= aNbGroups; i++) {
617 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
621 TopoDS_Shape aGroupShape = aGroup->GetValue();
622 BRepBuilderAPI_Transform aTransformationShapeInv (aGroupShape, aTrsfInv, Standard_False);
623 TopoDS_Shape aGroupShapeTrsfInv = aTransformationShapeInv.Shape();
625 TopTools_IndexedMapOfShape anEdgesMap;
626 TopExp::MapShapes(aGroupShapeTrsfInv,TopAbs_EDGE, anEdgesMap);
627 Standard_Integer nbEdges = anEdgesMap.Extent();
629 if (shapeType == TSHAPE_BASIC) {
630 if ((nbEdges >= 21) || /*R1Ext = R2Ext*/(nbEdges == 17)) { // 17, 17+8*{1,2,3}, 21, 21+8*{1,2,3}
632 aGroup->SetName("THICKNESS");
634 else if (nbEdges == 6) {
635 if (!circularFoundAndAdded) {
636 circularFoundAndAdded = true;
638 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
641 else if (nbEdges == 8) {
642 incidentPipeFound = true;
643 mainPipeFound = false;
647 TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
649 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
650 double x=aP.X(), y=aP.Y(), z=aP.Z();
653 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
654 (Abs(y) > aR2Ext + Precision::Confusion())) {
655 incidentPipeFound = false;
658 if ( z < -Precision::Confusion()) {
659 // length of main pipe
660 mainPipeFound = true;
661 if (!mainPipeFoundAndAdded) {
662 mainPipeFoundAndAdded = true;
664 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
668 else if (Abs(x) > (theL1-Precision::Confusion())) {
669 // discretisation circulaire
671 if (!circularFoundAndAdded) {
672 circularFoundAndAdded = true;
674 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
679 if (incidentPipeFound) {
681 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
683 if (!addGroup && (!incidentPipeFound &&
687 // Flange (collerette)
690 aGroup->SetName("FLANGE");
696 else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
697 if (nbEdges >= 25) { // 25, 25+8, 25+16, 25+24
699 aGroup->SetName("THICKNESS");
701 else if ((nbEdges == 10) || (nbEdges == 6)) {
702 if (!circularFoundAndAdded) {
704 circularFoundAndAdded = true;
705 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
707 circularFound10 = true;
710 else if (!circularFound10 && nbEdges == 10) {
711 circularFound10 = true;
713 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
716 else if (nbEdges == 8) {
717 incidentPipeFound = true;
718 mainPipeFound = true;
721 bool isNearZ0 = false;
722 bool isBelowZ0 = false;
724 TopExp_Explorer Ex (aGroupShapeTrsfInv,TopAbs_VERTEX);
726 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
727 double x=aP.X(), y=aP.Y(), z=aP.Z();
729 // tuy_princ_long_avant & tuy_princ_long_apres
730 //bool isMain = (((z < Precision::Confusion()) || (x < Precision::Confusion())) &&
731 // ((y <= aR1Ext + Precision::Confusion()) ||
732 // (y <= -(aR1Ext + Precision::Confusion())) ||
733 // (y <= theR1 + Precision::Confusion()) ||
734 // (y == -(theR1 + Precision::Confusion()))));
735 bool isMain = ((z < Precision::Confusion() || x < Precision::Confusion()) &&
736 (fabs(y) > theR1 - Precision::Confusion() ||
737 fabs(y) < Precision::Confusion()));
740 mainPipeFound = false;
744 //if (z < Precision::Confusion() && !isMain) {
745 // flangeFound = true;
746 // if (!flangeFoundAndAdded) {
747 // flangeFoundAndAdded = true;
749 // aGroup->SetName("FLANGE");
752 if (fabs(z) < Precision::Confusion()) isNearZ0 = true;
753 if (z < - Precision::Confusion()) isBelowZ0 = true;
756 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
757 (Abs(y) > aR2Ext + Precision::Confusion())) {
758 incidentPipeFound = false;
764 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
766 if (incidentPipeFound) {
768 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
770 if (isNearZ0 && !isBelowZ0) {
772 if (!flangeFoundAndAdded) {
773 flangeFoundAndAdded = true;
775 aGroup->SetName("FLANGE");
778 if (!addGroup && (!incidentPipeFound &&
781 !chamferOrFilletFound)) {
783 chamferOrFilletFound = true;
784 if (shapeType == TSHAPE_CHAMFER)
785 aGroup->SetName("CHAMFER");
787 aGroup->SetName("FILLET");
793 // Add group to the list
795 theSeq->Append(aGroup);
803 //=============================================================================
805 * Return faces that are laying on surface.
807 //=============================================================================
808 bool AdvancedEngine_IOperations::GetFacesOnSurf
809 (const TopoDS_Shape &theShape,
810 const Handle_Geom_Surface& theSurface,
811 const Standard_Real theTolerance,
812 TopTools_ListOfShape &theFaces)
814 GEOMAlgo_FinderShapeOn1 aFinder;
816 aFinder.SetShape(theShape);
817 aFinder.SetTolerance(theTolerance);
818 aFinder.SetSurface(theSurface);
819 aFinder.SetShapeType(TopAbs_FACE);
820 aFinder.SetState(GEOMAlgo_ST_ON);
822 // Sets the minimal number of inner points for the faces that do not have own
823 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
825 aFinder.SetNbPntsMin(3);
826 // Sets the maximal number of inner points for edges or faces.
827 // It is usefull for the cases when this number is very big (e.g =2000) to improve
828 // the performance. If this value =0, all inner points will be taken into account.
830 aFinder.SetNbPntsMax(100);
833 // Interprete results
834 Standard_Integer iErr = aFinder.ErrorStatus();
835 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
837 MESSAGE(" iErr : " << iErr);
838 TCollection_AsciiString aMsg (" iErr : ");
839 aMsg += TCollection_AsciiString(iErr);
843 Standard_Integer iWrn = aFinder.WarningStatus();
844 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
846 MESSAGE(" *** iWrn : " << iWrn);
849 const TopTools_ListOfShape &aListRes = aFinder.Shapes(); // the result
850 TopTools_ListIteratorOfListOfShape anIter (aListRes);
852 for (; anIter.More(); anIter.Next()) {
853 theFaces.Append(anIter.Value());
859 //=============================================================================
861 * Creates and returns conical face.
863 //=============================================================================
864 TopoDS_Shape AdvancedEngine_IOperations::MakeConicalFace
865 (const gp_Ax2 &theAxis,
866 const double theRadius,
867 const double theRadiusThin,
868 const double theHeight,
869 const gp_Trsf &theTrsf)
871 BRepPrimAPI_MakeCone aMkCone (theAxis, theRadius, theRadiusThin, theHeight);
872 TopoDS_Shape aResult;
875 if (aMkCone.IsDone()) {
876 TopExp_Explorer anExp(aMkCone.Shape(), TopAbs_FACE);
878 for (; anExp.More(); anExp.Next()) {
879 TopoDS_Face aFace = TopoDS::Face(anExp.Current());
881 if (aFace.IsNull() == Standard_False) {
882 BRepAdaptor_Surface anAdaptor(aFace, Standard_False);
884 if (anAdaptor.GetType() == GeomAbs_Cone) {
885 // This is a conical face. Transform and return it.
886 BRepBuilderAPI_Transform aTransf(aFace, theTrsf, Standard_False);
888 aResult = aTransf.Shape();
898 //=============================================================================
900 * Generate the internal group of a Pipe T-Shape
902 //=============================================================================
903 bool AdvancedEngine_IOperations::MakeInternalGroup
904 (const Handle(GEOM_Object) &theShape,
905 const double theR1, const double theLen1,
906 const double theR2, const double theLen2,
907 const double theRL, double theTransLenL,
908 const double theRR, double theTransLenR,
909 const double theRI, double theTransLenI,
910 const Handle(TColStd_HSequenceOfTransient) &theSeq,
911 const gp_Trsf &theTrsf)
915 if (theShape.IsNull()) {
919 TopoDS_Shape aShape = theShape->GetValue();
921 if (aShape.IsNull()) {
922 SetErrorCode("Shape is not defined");
927 Standard_Real aMaxTol = -RealLast();
928 TopExp_Explorer anExp(aShape, TopAbs_VERTEX);
930 for (; anExp.More(); anExp.Next()) {
931 TopoDS_Vertex aVertex = TopoDS::Vertex(anExp.Current());
933 if (aVertex.IsNull() == Standard_False) {
934 const Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
936 if (aTol > aMaxTol) {
942 // Construct internal surfaces.
943 Standard_Integer i = 0;
944 const Standard_Integer aMaxNbSurf = 5;
945 Handle(Geom_Surface) aSurface[aMaxNbSurf];
946 TopTools_ListOfShape aConicalFaces;
947 Standard_Real aTolConf = Precision::Confusion();
949 // 1. Construct the internal surface of main pipe.
950 gp_Ax2 anAxis1 (gp::Origin(), gp::DX(), gp::DZ());
951 gp_Ax2 anAxis2 (gp::Origin(), gp::DZ(), gp::DX());
953 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theR1);
955 // 2. Construct the internal surface of incident pipe.
956 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theR2);
958 // 3. Construct the internal surface of left reduction pipe.
959 if (theRL > aTolConf) {
960 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRL);
962 if (theTransLenL > aTolConf) {
963 // 3.1. Construct the internal surface of left transition pipe.
964 gp_Pnt aPLeft (-theLen1, 0., 0.);
965 gp_Ax2 anAxisLeft (aPLeft, -gp::DX(), gp::DZ());
966 TopoDS_Shape aConeLeft =
967 MakeConicalFace(anAxisLeft, theR1, theRL, theTransLenL, theTrsf);
969 if (aConeLeft.IsNull() == Standard_False) {
970 aConicalFaces.Append(aConeLeft);
975 // 4. Construct the internal surface of right reduction pipe.
976 if (theRR > aTolConf) {
977 // There is no need to construct another cylinder of the same radius. Skip it.
978 if (Abs(theRR - theRL) > aTolConf) {
979 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRR);
982 if (theTransLenL > aTolConf) {
983 // 4.1. Construct the internal surface of right transition pipe.
984 gp_Pnt aPRight (theLen1, 0., 0.);
985 gp_Ax2 anAxisRight (aPRight, gp::DX(), gp::DZ());
986 TopoDS_Shape aConeRight =
987 MakeConicalFace(anAxisRight, theR1, theRR, theTransLenR, theTrsf);
989 if (aConeRight.IsNull() == Standard_False) {
990 aConicalFaces.Append(aConeRight);
995 // 5. Construct the internal surface of incident reduction pipe.
996 if (theRI > aTolConf) {
997 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theRI);
999 if (theTransLenI > aTolConf) {
1000 // 5.1. Construct the internal surface of incident transition pipe.
1001 gp_Pnt aPInci (0., 0., theLen2);
1002 gp_Ax2 anAxisInci (aPInci, gp::DZ(), gp::DX());
1003 TopoDS_Shape aConeInci =
1004 MakeConicalFace(anAxisInci, theR2, theRI, theTransLenI, theTrsf);
1006 if (aConeInci.IsNull() == Standard_False) {
1007 aConicalFaces.Append(aConeInci);
1012 // Get faces that are laying on cylindrical surfaces.
1013 TopTools_ListOfShape aFaces;
1014 gp_Trsf anInvTrsf = theTrsf.Inverted();
1016 for (i = 0; i < aMaxNbSurf; i++) {
1017 if (aSurface[i].IsNull()) {
1021 aSurface[i]->Transform(theTrsf);
1023 TopTools_ListOfShape aLocalFaces;
1025 if (!GetFacesOnSurf(aShape, aSurface[i], aMaxTol, aLocalFaces)) {
1030 // Check if the result contains outer cylinders.
1031 // It is required for main and incident pipes.
1032 TopTools_ListIteratorOfListOfShape anIter(aLocalFaces);
1034 while (anIter.More()) {
1035 TopExp_Explorer anExp(anIter.Value(), TopAbs_VERTEX);
1036 Standard_Boolean isInside = Standard_False;
1038 // Get a vertex from this shape
1040 TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
1042 if (aVtx.IsNull() == Standard_False) {
1043 gp_Pnt aPnt = BRep_Tool::Pnt(aVtx);
1045 aPnt.Transform(anInvTrsf);
1048 // Check if the point is inside the main pipe.
1049 isInside = (Abs(aPnt.X()) <= theLen1);
1051 // Check if the point is inside the incident pipe.
1052 isInside = (aPnt.Z() <= theLen2);
1061 // Remove this face.
1062 aLocalFaces.Remove(anIter);
1067 aFaces.Append(aLocalFaces);
1070 // Get faces that are laying on conical faces.
1071 if (aConicalFaces.IsEmpty() == Standard_False) {
1072 Handle(GEOM_Object) aCone =
1073 GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1074 Handle(GEOM_Function) aFunction =
1075 aCone->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1076 TopTools_ListIteratorOfListOfShape aFIter(aConicalFaces);
1077 Handle(GEOM_Object) aConeFromShape;
1079 for (; aFIter.More(); aFIter.Next()) {
1080 aFunction->SetValue(aFIter.Value());
1081 aConeFromShape = myShapesOperations->GetInPlace(theShape, aCone);
1083 if (aConeFromShape.IsNull() == Standard_False) {
1084 aConeFromShape->GetLastFunction()->SetDescription("");
1085 TopoDS_Shape aConeFaces = aConeFromShape->GetValue();
1086 TopExp_Explorer anExp(aConeFaces, TopAbs_FACE);
1088 for (; anExp.More(); anExp.Next()) {
1089 TopoDS_Face aConeFace = TopoDS::Face(anExp.Current());
1091 if (aConeFace.IsNull() == Standard_False) {
1092 aFaces.Append(aConeFace);
1099 // Create a group of internal faces.
1100 if (aFaces.IsEmpty() == Standard_False) {
1101 Handle(GEOM_Object) aGroup = myGroupOperations->CreateGroup(theShape, TopAbs_FACE);
1103 if (aGroup.IsNull() == Standard_False) {
1104 aGroup->GetLastFunction()->SetDescription("");
1105 aGroup->SetName("INTERNAL_FACES");
1107 TopTools_IndexedMapOfShape anIndices;
1108 Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger;
1110 TopExp::MapShapes(aShape, anIndices);
1112 TopTools_ListIteratorOfListOfShape anIter(aFaces);
1114 for (; anIter.More(); anIter.Next()) {
1115 const TopoDS_Shape &aFace = anIter.Value();
1116 const Standard_Integer anIndex = anIndices.FindIndex(aFace);
1119 aSeqIDs->Append(anIndex);
1123 myGroupOperations->UnionIDs(aGroup, aSeqIDs);
1124 aGroup->GetLastFunction()->SetDescription("");
1125 theSeq->Append(aGroup);
1134 bool AdvancedEngine_IOperations::MakePipeTShapePartition(Handle(GEOM_Object) theShape,
1135 double theR1, double theW1, double theL1,
1136 double theR2, double theW2, double theL2,
1137 double theH, double theW,
1138 double theRF, bool isNormal)
1142 // Build tools for partition operation:
1143 // 1 face and 2 planes
1145 Handle(GEOM_Object) arete_intersect_int, arete_intersect_ext;
1146 Handle(GEOM_Object) wire_t, wire_t2, face_t, face_t2;
1147 Handle(GEOM_Object) chan_racc;
1148 Handle(GEOM_Object) vi1, vi2;
1149 Handle(GEOM_Object) Te3;
1153 Handle(GEOM_Object) Vector_Z = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1154 Vector_Z->GetLastFunction()->SetDescription("");
1157 double aSize = 2*(theL1 + theL2);
1158 double aR1Ext = theR1 + theW1;
1159 double aR2Ext = theR2 + theW2;
1160 double theVertCylinderRadius = aR2Ext + theW + theRF;
1161 double theHoriCylinderRadius = aR1Ext + theH + theRF;
1163 // Common edges on internal cylinder
1164 Handle(GEOM_Object) box_i = my3DPrimOperations->MakeBoxDXDYDZ(theR2, theR2, theR1);
1165 box_i->GetLastFunction()->SetDescription("");
1166 box_i = myTransformOperations->TranslateDXDYDZ(box_i, -theR2, -theR2, 0);
1167 box_i->GetLastFunction()->SetDescription("");
1169 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1170 TCollection_AsciiString theDesc = aFunction->GetDescription();
1171 Handle(TColStd_HSequenceOfTransient) edges_i =
1172 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1173 // Recover previous description to get rid of Propagate dump
1174 aFunction->SetDescription(theDesc);
1175 if (edges_i.IsNull() || edges_i->Length() == 0) {
1176 SetErrorCode("Internal edges not found");
1179 for (int i=1; i<=edges_i->Length();i++) {
1180 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_i->Value(i));
1181 anObj->GetLastFunction()->SetDescription("");
1183 arete_intersect_int = Handle(GEOM_Object)::DownCast(edges_i->Value(1));
1185 // search for vertices located on both internal pipes
1186 aFunction = theShape->GetLastFunction();
1187 theDesc = aFunction->GetDescription();
1188 Handle(TColStd_HSequenceOfTransient) vertices_i =
1189 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1190 // Recover previous description to get rid of Propagate dump
1191 aFunction->SetDescription(theDesc);
1192 if (vertices_i.IsNull() || vertices_i->Length() == 0) {
1193 SetErrorCode("Internal vertices not found");
1197 double d1min = theR2+theW2, d2min=theR2+theW2;
1198 for (int i = 1; i <= vertices_i->Length(); i++) {
1199 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_i->Value(i));
1200 v->GetLastFunction()->SetDescription("");
1201 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1202 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1203 if (Abs(aP.X()) <= Precision::Confusion()) {
1204 if (Abs(aP.Y()) < d1min) {
1206 d1min = Abs(aP.Y());
1208 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1209 if (Abs(aP.X()) < d2min) {
1211 d2min = Abs(aP.X());
1215 if (vi1.IsNull() || vi2.IsNull()) {
1216 SetErrorCode("Cannot find internal intersection vertices");
1220 std::list<Handle(GEOM_Object)> theShapes;
1223 Handle(GEOM_Object) ve1, ve2;
1224 TopoDS_Vertex vertex1, vertex2;
1226 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ(aR2Ext, aR2Ext, aR1Ext);
1227 box_e->GetLastFunction()->SetDescription("");
1228 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -aR2Ext, -aR2Ext, 0);
1229 box_e->GetLastFunction()->SetDescription("");
1231 // search for vertices located on both external pipes
1232 aFunction = theShape->GetLastFunction();
1233 theDesc = aFunction->GetDescription();
1234 Handle(TColStd_HSequenceOfTransient) vertices_e =
1235 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1236 // Recover previous description to get rid of Propagate dump
1237 aFunction->SetDescription(theDesc);
1238 if (vertices_e.IsNull() || vertices_e->Length() == 0) {
1239 SetErrorCode("External vertices not found");
1243 double d1max = 0, d2max = 0;
1244 for (int i = 1; i <= vertices_e->Length(); i++) {
1245 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_e->Value(i));
1246 v->GetLastFunction()->SetDescription("");
1247 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1248 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1249 if (Abs(aP.X()) <= Precision::Confusion()) {
1250 if (Abs(aP.Y()) > d1max) {
1253 d1max = Abs(aP.Y());
1255 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1256 if (Abs(aP.X()) > d2max) {
1259 d2max = Abs(aP.X());
1263 if (ve1.IsNull() || ve2.IsNull()) {
1264 SetErrorCode("Cannot find external intersection vertices");
1267 Handle(GEOM_Object) edge_e1, edge_e2;
1269 // Common edges on external cylinder
1270 aFunction = theShape->GetLastFunction();
1271 theDesc = aFunction->GetDescription();
1272 Handle(TColStd_HSequenceOfTransient) edges_e =
1273 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1274 // Recover previous description to get rid of Propagate dump
1275 aFunction->SetDescription(theDesc);
1276 if (edges_e.IsNull() || edges_e->Length() == 0) {
1277 SetErrorCode("External edges not found");
1280 ShapeAnalysis_Edge sae;
1281 for (int i=1; i<=edges_e->Length();i++) {
1282 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
1283 anObj->GetLastFunction()->SetDescription("");
1284 TopoDS_Edge anEdge = TopoDS::Edge(anObj->GetValue());
1285 if ( !anEdge.IsNull() &&
1286 (sae.FirstVertex(anEdge).IsSame(vertex1) || sae.LastVertex(anEdge).IsSame(vertex1)) &&
1287 (sae.FirstVertex(anEdge).IsSame(vertex2) || sae.LastVertex(anEdge).IsSame(vertex2))) {
1288 arete_intersect_ext = anObj;
1292 edge_e1 = myBasicOperations->MakeLineTwoPnt(ve1, vi1);
1293 if (edge_e1.IsNull()) {
1294 SetErrorCode("Edge 1 could not be built");
1298 edge_e2 = myBasicOperations->MakeLineTwoPnt(ve2, vi2);
1299 if (edge_e2.IsNull()) {
1300 SetErrorCode("Edge 2 could not be built");
1304 edge_e1->GetLastFunction()->SetDescription("");
1305 edge_e2->GetLastFunction()->SetDescription("");
1307 std::list<Handle(GEOM_Object)> edge_e_elist;
1308 edge_e_elist.push_back(arete_intersect_int);
1309 edge_e_elist.push_back(edge_e1);
1310 edge_e_elist.push_back(arete_intersect_ext);
1311 edge_e_elist.push_back(edge_e2);
1312 wire_t = myShapesOperations->MakeWire(edge_e_elist, 1e-7);
1313 if (wire_t.IsNull()) {
1314 SetErrorCode("Impossible to build wire");
1317 wire_t->GetLastFunction()->SetDescription("");
1318 face_t = myShapesOperations->MakeFace(wire_t, false);
1319 if (face_t.IsNull()) {
1320 SetErrorCode("Impossible to build face");
1323 face_t->GetLastFunction()->SetDescription("");
1325 theShapes.push_back(theShape);
1326 theShapes.push_back(vi1);
1327 theShapes.push_back(vi2);
1328 theShapes.push_back(ve1);
1329 theShapes.push_back(ve2);
1330 theShapes.push_back(edge_e1);
1331 theShapes.push_back(edge_e2);
1332 theShapes.push_back(wire_t);
1333 theShapes.push_back(face_t);
1336 Handle(GEOM_Object) P1, P2, P3, P4, P5, P6;
1337 int idP1, idP2, idP3, idP4;
1340 std::vector<int> LX;
1341 std::vector<int> LY;
1342 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ
1343 (theVertCylinderRadius, theVertCylinderRadius, theHoriCylinderRadius);
1344 box_e->GetLastFunction()->SetDescription("");
1345 box_e = myTransformOperations->TranslateDXDYDZ
1346 (box_e, -theVertCylinderRadius, -theVertCylinderRadius, 0);
1347 box_e->GetLastFunction()->SetDescription("");
1349 aFunction = theShape->GetLastFunction();
1350 theDesc = aFunction->GetDescription();
1351 Handle(TColStd_HSequenceOfTransient) extremVertices =
1352 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1353 // Recover previous description to get rid of Propagate dump
1354 aFunction->SetDescription(theDesc);
1356 if (extremVertices.IsNull() || extremVertices->Length() == 0) {
1358 SetErrorCode("Vertices on chamfer not found");
1360 SetErrorCode("Vertices on fillet not found");
1364 theShapes.push_back(theShape);
1365 theShapes.push_back(box_e);
1366 if (extremVertices->Length() != 6) {
1367 // for (int i=1; i<=extremVertices->Length(); i++){
1368 // theShapes.push_back(Handle(GEOM_Object)::DownCast(extremVertices->Value(i)));
1370 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1371 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1372 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1373 SetErrorCode("Bad number of vertices on chamfer found");
1377 for (int i=1; i<=extremVertices->Length(); i++){
1378 Handle(GEOM_Object) aV = Handle(GEOM_Object)::DownCast(extremVertices->Value(i));
1379 aV->GetLastFunction()->SetDescription("");
1380 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aV->GetValue()));
1382 if (Abs(aP.X()) <= Precision::Confusion()) {
1383 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
1385 if (aP.Z()-ZX > Precision::Confusion()) {
1392 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
1394 if (aP.Z() - ZY > Precision::Confusion()) {
1405 if (LX.at(0) == PZX)
1408 if (LY.at(0) == PZY)
1411 P1 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP1));
1412 P2 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP2));
1413 P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
1414 P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4));
1416 Handle(GEOM_Object) Cote_1 = myBasicOperations->MakeLineTwoPnt(P1, vi1);
1417 if (Cote_1.IsNull()) {
1418 SetErrorCode("Impossible to build edge in thickness");
1421 Cote_1->GetLastFunction()->SetDescription("");
1423 Handle(GEOM_Object) Cote_2 = myBasicOperations->MakeLineTwoPnt(vi2, P3);
1424 if (Cote_2.IsNull()) {
1425 SetErrorCode("Impossible to build edge in thickness");
1428 Cote_2->GetLastFunction()->SetDescription("");
1430 // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
1431 // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
1432 // std::cerr << "Getting chamfer edge on main pipe" << std::endl;
1433 Handle(GEOM_Object) edge_chan_princ = myBlocksOperations->GetEdge(theShape, P1, P3);
1434 if (edge_chan_princ.IsNull()) {
1435 SetErrorCode("Impossible to find edge on main pipe");
1438 edge_chan_princ->GetLastFunction()->SetDescription("");
1440 Handle(GEOM_Object) edge_chan_inc = myBlocksOperations->GetEdge(theShape, P2, P4);
1441 if (edge_chan_inc.IsNull()) {
1442 SetErrorCode("Impossible to find edge on incident pipe");
1445 edge_chan_inc->GetLastFunction()->SetDescription("");
1447 std::list<Handle(GEOM_Object)> edgeList1;
1448 edgeList1.push_back(edge_chan_princ);
1449 edgeList1.push_back(Cote_1);
1450 edgeList1.push_back(arete_intersect_int);
1451 edgeList1.push_back(Cote_2);
1453 // std::cerr << "Creating wire 1" << std::endl;
1454 wire_t = myShapesOperations->MakeWire(edgeList1, 1e-7);
1455 if (wire_t.IsNull()) {
1456 SetErrorCode("Impossible to build wire");
1459 wire_t->GetLastFunction()->SetDescription("");
1461 // std::cerr << "Creating face 1" << std::endl;
1462 face_t = myShapesOperations->MakeFace(wire_t, false);
1463 if (face_t.IsNull()) {
1464 SetErrorCode("Impossible to build face");
1467 face_t->GetLastFunction()->SetDescription("");
1468 theShapes.push_back(face_t);
1470 gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(P2->GetValue()));
1471 gp_Pnt aP5 = BRep_Tool::Pnt(TopoDS::Vertex(vi1->GetValue()));
1472 double deltaZ = aP2.Z() - aP5.Z();
1473 // std::cerr << "Creating new point from vi1 with deltaZ = " << deltaZ << std::endl;
1474 Handle(GEOM_Object) P5bis = myTransformOperations->TranslateDXDYDZCopy(vi1, 0, 0, deltaZ);
1475 if (P5bis.IsNull()) {
1476 SetErrorCode("Impossible to translate vertex");
1479 P5bis->GetLastFunction()->SetDescription("");
1481 gp_Pnt aP4 = BRep_Tool::Pnt(TopoDS::Vertex(P4->GetValue()));
1482 gp_Pnt aP6 = BRep_Tool::Pnt(TopoDS::Vertex(vi2->GetValue()));
1483 deltaZ = aP4.Z() - aP6.Z();
1484 // std::cerr << "Creating new point from vi2 with deltaZ = " << deltaZ << std::endl;
1485 Handle(GEOM_Object) P6bis = myTransformOperations->TranslateDXDYDZCopy(vi2, 0, 0, deltaZ);
1486 if (P6bis.IsNull()) {
1487 SetErrorCode("Impossible to translate vertex");
1490 P6bis->GetLastFunction()->SetDescription("");
1492 // std::cerr << "Creating new line 1 from 2 previous points" << std::endl;
1493 Handle(GEOM_Object) Cote_3 = myBasicOperations->MakeLineTwoPnt(P5bis, P2);
1494 if (Cote_3.IsNull()) {
1495 SetErrorCode("Impossible to build edge in thickness");
1498 Cote_3->GetLastFunction()->SetDescription("");
1500 // std::cerr << "Creating new line 2 from 2 previous points" << std::endl;
1501 Handle(GEOM_Object) Cote_4 = myBasicOperations->MakeLineTwoPnt(P6bis, P4);
1502 if (Cote_4.IsNull()) {
1503 SetErrorCode("Impossible to build edge in thickness");
1506 Cote_4->GetLastFunction()->SetDescription("");
1508 // std::cerr << "Creating new line 3 from 2 previous points" << std::endl;
1509 Handle(GEOM_Object) Cote_5 = myBasicOperations->MakeLineTwoPnt(P5bis, P6bis);
1510 if (Cote_4.IsNull()) {
1511 SetErrorCode("Impossible to build edge in thickness");
1514 Cote_5->GetLastFunction()->SetDescription("");
1516 //std::list<Handle(GEOM_Object)> edgeList2;
1517 //edgeList2.push_back(edge_chan_inc);
1518 //edgeList2.push_back(Cote_3);
1519 //edgeList2.push_back(Cote_5);
1520 //edgeList2.push_back(Cote_4);
1521 // std::cerr << "Creating wire 2" << std::endl;
1522 //wire_t2 = myShapesOperations->MakeWire(edgeList2, 1e-7);
1523 //if (wire_t2.IsNull()) {
1524 // SetErrorCode("Impossible to build wire");
1527 //wire_t2->GetLastFunction()->SetDescription("");
1528 // std::cerr << "Creating face 2" << std::endl;
1529 //face_t2 = myShapesOperations->MakeFace(wire_t2, false);
1531 // Mantis issue 0021682
1532 face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - (theR2 + theW2));
1533 //face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - 2.0*theR2);
1534 if (face_t2.IsNull()) {
1535 SetErrorCode("Impossible to build face");
1538 face_t2->GetLastFunction()->SetDescription("");
1539 theShapes.push_back(face_t2);
1543 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1544 Handle(GEOM_Object) aVZ = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1545 Handle(GEOM_Object) aVXZ = myBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
1546 Handle(GEOM_Object) aPlnOZ = myBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
1547 Handle(GEOM_Object) aPlnOXZ = myBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
1548 aP0->GetLastFunction()->SetDescription("");
1549 aVZ->GetLastFunction()->SetDescription("");
1550 aVXZ->GetLastFunction()->SetDescription("");
1551 aPlnOZ->GetLastFunction()->SetDescription("");
1552 aPlnOXZ->GetLastFunction()->SetDescription("");
1553 theShapes.push_back(aPlnOZ);
1554 theShapes.push_back(aPlnOXZ);
1557 Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
1558 Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
1559 Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
1560 Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
1561 Handle(TColStd_HArray1OfInteger) theMaterials;
1563 partitionShapes->Append(theShape);
1564 theTools->Append(aPlnOZ);
1565 if (Abs(aR1Ext - aR2Ext) > Precision::Confusion())
1566 theTools->Append(aPlnOXZ);
1567 theTools->Append(face_t);
1569 theTools->Append(face_t2);
1571 Te3 = myBooleanOperations->MakePartition
1572 (partitionShapes, theTools, theKeepInside, theRemoveInside,
1573 TopAbs_SOLID, false, theMaterials, 0, false, Standard_False);
1575 SetErrorCode("Impossible to build partition of TShape");
1578 Te3->GetLastFunction()->SetDescription("");
1580 // Last verification: result should be a block
1581 std::list<GEOMImpl_IBlocksOperations::BCError> errList;
1582 if (!myBlocksOperations->CheckCompoundOfBlocks(Te3,errList)) {
1583 SetErrorCode("TShape is not a compound of block");
1587 // // BEGIN Compound of created shapes - Only for debug purpose
1588 // theShapes.clear();
1589 // theShapes.push_back(theShape);
1590 // theShapes.push_back(aPlnOZ);
1591 // if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
1592 // theShapes.push_back(aPlnOXZ);
1593 // theShapes.push_back(face_t);
1595 // theShapes.push_back(face_t2);
1597 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1598 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1599 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1600 // // END Compound of created shapes - Only for debug purpose
1602 TopoDS_Shape aShape = Te3->GetValue();
1603 theShape->GetLastFunction()->SetValue(aShape);
1605 catch (Standard_Failure) {
1606 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1607 SetErrorCode(aFail->GetMessageString());
1615 // Mirror and glue faces
1616 bool AdvancedEngine_IOperations::MakePipeTShapeMirrorAndGlue(Handle(GEOM_Object) theShape,
1617 double theR1, double theW1, double theL1,
1618 double theR2, double theW2, double theL2)
1623 double aSize = 2*(theL1 + theL2);
1624 double aR1Ext = theR1 + theW1;
1627 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1628 aP0->GetLastFunction()->SetDescription("");
1629 Handle(GEOM_Object) aVX = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
1630 Handle(GEOM_Object) aVY = myBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
1631 aVX->GetLastFunction()->SetDescription("");
1632 aVY->GetLastFunction()->SetDescription("");
1633 Handle(GEOM_Object) aPlane_OX = myBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
1634 Handle(GEOM_Object) aPlane_OY = myBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
1635 aPlane_OX->GetLastFunction()->SetDescription("");
1636 aPlane_OY->GetLastFunction()->SetDescription("");
1638 Handle(GEOM_Object) Te4 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
1640 SetErrorCode("Impossible to build mirror of quarter TShape");
1644 Handle(GEOM_Object) Te5 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
1646 SetErrorCode("Impossible to build mirror of half TShape");
1650 Handle(GEOM_Object) Te6 = myTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
1652 SetErrorCode("Impossible to build mirror of half TShape");
1656 std::list<Handle(GEOM_Object)> aShapesList;
1657 aShapesList.push_back(theShape);
1658 aShapesList.push_back(Te4);
1659 aShapesList.push_back(Te5);
1660 aShapesList.push_back(Te6);
1661 Handle(GEOM_Object) Te7 = myShapesOperations->MakeCompound(aShapesList);
1663 SetErrorCode("Impossible to build compound");
1667 // Copy source shape
1668 TopoDS_Shape aShapeCopy;
1669 TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
1670 TNaming_CopyShape::CopyTool(Te7->GetValue(), aMapTShapes, aShapeCopy);
1672 Handle(GEOM_Object) Te8 = myShapesOperations->MakeGlueFaces(Te7, 1e-7, true);
1674 SetErrorCode("Impossible to glue faces of TShape");
1678 TopoDS_Shape aShape = Te8->GetValue();
1679 BRepCheck_Analyzer anAna (aShape, Standard_True);
1681 if (!anAna.IsValid()) {
1682 // Try to do gluing with the tolerance equal to maximal
1683 // tolerance of vertices of the source shape.
1684 Standard_Real aTolMax = -RealLast();
1686 for (TopExp_Explorer ExV (aShapeCopy, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1687 TopoDS_Vertex aVertex = TopoDS::Vertex(ExV.Current());
1688 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
1690 if (aTol > aTolMax) {
1696 Te7->GetLastFunction()->SetValue(aShapeCopy);
1697 Te8 = myShapesOperations->MakeGlueFaces(Te7, aTolMax, true);
1700 SetErrorCode("Impossible to glue faces of TShape");
1704 aShape = Te8->GetValue();
1708 theShape->GetLastFunction()->SetValue(aShape);
1710 Te4->GetLastFunction()->SetDescription("");
1711 Te5->GetLastFunction()->SetDescription("");
1712 Te6->GetLastFunction()->SetDescription("");
1713 Te7->GetLastFunction()->SetDescription("");
1714 Te8->GetLastFunction()->SetDescription("");
1720 //=======================================================================
1721 //function : MakePipeTShapeThicknessReduction
1722 //purpose : Static method. Add thiskness reduction elements at the three
1723 // open ends of the T-Shape.
1724 //=======================================================================
1725 TopoDS_Shape AdvancedEngine_IOperations::MakePipeTShapeThicknessReduction
1726 (TopoDS_Shape theShape,
1727 double r1, double w1, double l1,
1728 double r2, double w2, double l2,
1729 double rL, double wL, double ltransL, double lthinL,
1730 double rR, double wR, double ltransR, double lthinR,
1731 double rI, double wI, double ltransI, double lthinI,
1732 bool fuseReductions)
1734 // Add thickness reduction elements
1735 // at the three extremities: Left, Right and Incident
1737 // ---------------------.
1739 // ---------------------. \
1740 // ^ \ '-----------------.
1742 // | '-----------------'
1744 // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--
1747 TopoDS_Shape aResult = theShape;
1748 double aTol = Precision::Confusion();
1750 gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
1752 // Left reduction (rL, wL, ltransL, lthinL)
1753 if (rL > aTol && wL > aTol && ltransL > aTol) {
1754 gp_Pnt aPLeft (-l1, 0, 0);
1755 gp_Ax2 anAxesLeft (aPLeft, -aVX, aVZ);
1756 TopoDS_Shape aReductionLeft = AdvancedEngine_IOperations::MakeThicknessReduction
1757 (anAxesLeft, r1, w1, rL, wL, ltransL, lthinL, fuseReductions);
1759 if (fuseReductions) {
1760 BRepAlgoAPI_Fuse fuseL (aResult, aReductionLeft);
1761 if (!fuseL.IsDone())
1762 StdFail_NotDone::Raise("Cannot fuse Te with left reduction");
1763 aResult = fuseL.Shape();
1770 B.Add(C, aReductionLeft);
1776 if (rR > aTol && wR > aTol && ltransR > aTol) {
1777 gp_Pnt aPRight (l1, 0, 0);
1778 gp_Ax2 anAxesRight (aPRight, aVX, aVZ);
1779 TopoDS_Shape aReductionRight = AdvancedEngine_IOperations::MakeThicknessReduction
1780 (anAxesRight, r1, w1, rR, wR, ltransR, lthinR, fuseReductions);
1782 if (fuseReductions) {
1783 BRepAlgoAPI_Fuse fuseR (aResult, aReductionRight);
1784 if (!fuseR.IsDone())
1785 StdFail_NotDone::Raise("Cannot fuse Te with right reduction");
1786 aResult = fuseR.Shape();
1793 B.Add(C, aReductionRight);
1798 // Incident reduction
1799 if (rI > aTol && wI > aTol && ltransI > aTol) {
1800 gp_Pnt aPInci (0, 0, l2);
1801 gp_Ax2 anAxesInci (aPInci, aVZ, aVX);
1802 TopoDS_Shape aReductionInci = AdvancedEngine_IOperations::MakeThicknessReduction
1803 (anAxesInci, r2, w2, rI, wI, ltransI, lthinI, fuseReductions);
1805 if (fuseReductions) {
1806 BRepAlgoAPI_Fuse fuseInci (aResult, aReductionInci);
1807 if (!fuseInci.IsDone())
1808 StdFail_NotDone::Raise("Cannot fuse Te with incident reduction");
1809 aResult = fuseInci.Shape();
1816 B.Add(C, aReductionInci);
1821 // Get rid of extra compounds
1822 TopTools_ListOfShape listShapeRes;
1823 GEOMUtils::AddSimpleShapes(aResult, listShapeRes);
1824 aResult = listShapeRes.First(); // useful for the case "fuseReductions == true"
1826 if (!fuseReductions && listShapeRes.Extent() > 1) {
1827 // Simplify T-Shape compound (get rid of sub-compounds) and glue duplicated faces
1832 TopTools_ListIteratorOfListOfShape itSub (listShapeRes);
1833 for (; itSub.More(); itSub.Next())
1834 B.Add(C, itSub.Value());
1837 aResult = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
1843 //=======================================================================
1844 //function : MakeThicknessReduction
1845 //purpose : Static method. Create one thickness reduction element.
1846 //=======================================================================
1847 TopoDS_Shape AdvancedEngine_IOperations::MakeThicknessReduction (gp_Ax2 theAxes,
1848 const double R, const double W,
1849 const double Rthin, const double Wthin,
1850 const double Ltrans, const double Lthin,
1853 double aTol = Precision::Confusion();
1854 if (Rthin < aTol || Wthin < aTol || Ltrans < aTol) {
1855 StdFail_NotDone::Raise("Cannot build thickness reduction: too small values");
1857 bool isThinPart = (Lthin > aTol);
1862 // ^ \ '-----------------.
1864 // | '-----------------'
1866 // --.--.--.--.--.--.--.--.--.--.--.--.--> theAxes.Direction()
1869 double RExt = R + W;
1870 double RthinExt = Rthin + Wthin;
1872 gp_Dir aNormal = theAxes.Direction();
1873 gp_Dir anXDir = theAxes.XDirection();
1874 gp_Pnt aPntCyl (theAxes.Location().XYZ() + aNormal.XYZ()*Ltrans);
1875 gp_Ax2 anAxesCyl (aPntCyl, aNormal, anXDir);
1877 // Build the transition part
1878 BRepPrimAPI_MakeCone ConeExt (theAxes, RExt, RthinExt, Ltrans);
1879 BRepPrimAPI_MakeCone ConeInt (theAxes, R, Rthin, Ltrans);
1882 if (!ConeExt.IsDone() || !ConeInt.IsDone())
1883 StdFail_NotDone::Raise("Cannot build cones of thickness reduction");
1884 BRepAlgoAPI_Cut cut1 (ConeExt.Shape(), ConeInt.Shape());
1886 StdFail_NotDone::Raise("Coudn't build transition part of thickness reduction");
1887 TopoDS_Shape aReduction = cut1.Shape();
1889 // Build the thin part, if required
1890 TopoDS_Shape aThinPart;
1892 BRepPrimAPI_MakeCylinder CExt (anAxesCyl, RthinExt, Lthin);
1893 BRepPrimAPI_MakeCylinder CInt (anAxesCyl, Rthin, Lthin);
1896 if (!CExt.IsDone() || !CInt.IsDone())
1897 StdFail_NotDone::Raise("Cannot build cylinders of thickness reduction");
1898 BRepAlgoAPI_Cut cut2 (CExt.Shape(), CInt.Shape());
1900 StdFail_NotDone::Raise("Coudn't build thin part of thickness reduction");
1901 aThinPart = cut2.Shape();
1907 BRepAlgoAPI_Fuse fuse1 (aReduction, aThinPart);
1908 if (!fuse1.IsDone())
1909 StdFail_NotDone::Raise("Cannot fuse parts of thickness reduction");
1910 aReduction = fuse1.Shape();
1914 // Partition the reduction on blocks
1915 gp_Ax3 anAxesPln1 (aPntCyl, theAxes.XDirection(), aNormal);
1916 gp_Ax3 anAxesPln2 (aPntCyl, theAxes.YDirection(), aNormal);
1917 gp_Pln aPln1 (anAxesPln1);
1918 gp_Pln aPln2 (anAxesPln2);
1919 double aSize = Ltrans + Lthin + R + Rthin + Wthin; // to guarantee enough size in all directions
1920 TopoDS_Shape aTool1 = BRepBuilderAPI_MakeFace(aPln1, -aSize, +aSize, -aSize, +aSize).Shape();
1921 TopoDS_Shape aTool2 = BRepBuilderAPI_MakeFace(aPln2, -aSize, +aSize, -aSize, +aSize).Shape();
1923 GEOMAlgo_Splitter PS;
1924 PS.AddArgument(aReduction);
1926 PS.AddArgument(aThinPart);
1929 PS.SetLimit(TopAbs_SOLID);
1932 aReduction = PS.Shape();
1938 //=============================================================================
1941 * \brief Create a T-shape object with specified caracteristics for the main and
1942 * the incident pipes (radius, width, half-length).
1943 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1944 * \param theR1 Internal radius of main pipe
1945 * \param theW1 Width of main pipe
1946 * \param theL1 Half-length of main pipe
1947 * \param theR2 Internal radius of incident pipe (R2 < R1)
1948 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1949 * \param theL2 Half-length of incident pipe
1950 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1951 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1953 //=============================================================================
1954 Handle(TColStd_HSequenceOfTransient)
1955 AdvancedEngine_IOperations::MakePipeTShape(double theR1, double theW1, double theL1,
1956 double theR2, double theW2, double theL2,
1957 double theRL, double theWL, double theLtransL, double theLthinL,
1958 double theRR, double theWR, double theLtransR, double theLthinR,
1959 double theRI, double theWI, double theLtransI, double theLthinI,
1962 MESSAGE("AdvancedEngine_IOperations::MakePipeTShape");
1965 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1967 //Add a new shape function with parameters
1968 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1969 if (aFunction.IsNull()) return NULL;
1971 //Check if the function is set correctly
1972 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
1974 AdvancedEngine_IPipeTShape aData (aFunction);
1982 aData.SetHexMesh(theHexMesh);
1984 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
1985 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
1986 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
1988 //Compute the resulting value
1991 if (!GetSolver()->ComputeFunction(aFunction)) {
1992 SetErrorCode("TShape driver failed");
1997 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1999 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2003 if (isTRL || isTRR || isTRI) {
2004 // Add thickness reduction elements
2005 // at the three extremities: Left, Right and Incident
2006 TopoDS_Shape aResShape =
2007 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2008 theRL, theWL, theLtransL, theLthinL,
2009 theRR, theWR, theLtransR, theLthinR,
2010 theRI, theWI, theLtransI, theLthinI,
2012 aFunction->SetValue(aResShape);
2015 catch (Standard_Failure) {
2016 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2017 SetErrorCode(aFail->GetMessageString());
2021 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2022 aSeq->Append(aShape);
2027 if (!MakeGroups(aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2028 0., 0., 0., aSeq, gp_Trsf()))
2032 // Get internal group.
2033 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2034 theRR, theLtransR, theRI, theLtransI,
2039 catch (Standard_Failure) {
2040 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2041 SetErrorCode(aFail->GetMessageString());
2045 //Make a Python command
2046 TCollection_AsciiString anEntry, aListRes("[");
2047 // Iterate over the sequence aSeq
2048 Standard_Integer aNbGroups = aSeq->Length();
2049 Standard_Integer i = 1;
2050 for (; i <= aNbGroups; i++) {
2051 Handle(Standard_Transient) anItem = aSeq->Value(i);
2052 if (anItem.IsNull()) continue;
2053 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2054 if (aGroup.IsNull()) continue;
2055 //Make a Python command
2056 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2057 aListRes += anEntry + ", ";
2059 aListRes.Trunc(aListRes.Length() - 2);
2061 GEOM::TPythonDump pd (aFunction);
2063 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2064 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2065 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2068 // thickness reduction
2070 pd << ", theRL=" << theRL << ", theWL=" << theWL
2071 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2073 pd << ", theRR=" << theRR << ", theWR=" << theWR
2074 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2076 pd << ", theRI=" << theRI << ", theWI=" << theWI
2077 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2086 //=============================================================================
2088 * MakePipeTShapeWithPosition
2089 * Create a T-shape object with specified caracteristics for the main and
2090 * the incident pipes (radius, width, half-length).
2091 * The extremities of the main pipe are located on junctions points P1 and P2.
2092 * The extremity of the incident pipe is located on junction point P3.
2093 * \param theR1 Internal radius of main pipe
2094 * \param theW1 Width of main pipe
2095 * \param theL1 Half-length of main pipe
2096 * \param theR2 Internal radius of incident pipe (R2 < R1)
2097 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2098 * \param theL2 Half-length of incident pipe
2099 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2100 * \param theP1 1st junction point of main pipe
2101 * \param theP2 2nd junction point of main pipe
2102 * \param theP3 Junction point of incident pipe
2103 * \return List of GEOM_Objects, containing the created shape and propagation groups..
2105 //=============================================================================
2106 Handle(TColStd_HSequenceOfTransient)
2107 AdvancedEngine_IOperations::MakePipeTShapeWithPosition
2108 (double theR1, double theW1, double theL1,
2109 double theR2, double theW2, double theL2,
2110 double theRL, double theWL, double theLtransL, double theLthinL,
2111 double theRR, double theWR, double theLtransR, double theLthinR,
2112 double theRI, double theWI, double theLtransI, double theLthinI,
2114 Handle(GEOM_Object) theP1,
2115 Handle(GEOM_Object) theP2,
2116 Handle(GEOM_Object) theP3)
2120 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2124 //Add a new shape function with parameters
2125 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
2126 if (aFunction.IsNull()) return NULL;
2128 //Check if the function is set correctly
2129 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2131 // Check new position
2132 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2136 AdvancedEngine_IPipeTShape aData(aFunction);
2144 aData.SetHexMesh(theHexMesh);
2146 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2147 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2148 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2150 //Compute the resulting value
2153 if (!GetSolver()->ComputeFunction(aFunction)) {
2154 SetErrorCode("TShape driver failed");
2159 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2161 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2165 if (isTRL || isTRR || isTRI) {
2166 // Add thickness reduction elements
2167 // at the three extremities: Left, Right and Incident
2168 TopoDS_Shape aResShape =
2169 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2170 theRL, theWL, theLtransL, theLthinL,
2171 theRR, theWR, theLtransR, theLthinR,
2172 theRI, theWI, theLtransI, theLthinI,
2174 aFunction->SetValue(aResShape);
2177 catch (Standard_Failure) {
2178 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2179 SetErrorCode(aFail->GetMessageString());
2183 TopoDS_Shape Te = aShape->GetValue();
2186 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2187 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
2188 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2189 aFunction->SetValue(aTrsf_Shape);
2191 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2192 aSeq->Append(aShape);
2197 if (!MakeGroups(aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2198 0., 0., 0., aSeq, aTrsf)) {
2203 // Get internal group.
2204 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2205 theRR, theLtransR, theRI, theLtransI,
2210 catch (Standard_Failure) {
2211 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2212 SetErrorCode(aFail->GetMessageString());
2216 //Make a Python command
2217 TCollection_AsciiString anEntry, aListRes("[");
2218 // Iterate over the sequence aSeq
2219 Standard_Integer aNbGroups = aSeq->Length();
2220 Standard_Integer i = 1;
2221 for (; i <= aNbGroups; i++) {
2222 Handle(Standard_Transient) anItem = aSeq->Value(i);
2223 if (anItem.IsNull()) continue;
2224 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2225 if (aGroup.IsNull()) continue;
2226 //Make a Python command
2227 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2228 aListRes += anEntry + ", ";
2230 aListRes.Trunc(aListRes.Length() - 2);
2232 GEOM::TPythonDump pd (aFunction);
2234 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2235 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2236 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2237 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3;
2239 // thickness reduction
2241 pd << ", theRL=" << theRL << ", theWL=" << theWL
2242 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2244 pd << ", theRR=" << theRR << ", theWR=" << theWR
2245 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2247 pd << ", theRI=" << theRI << ", theWI=" << theWI
2248 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2257 //=============================================================================
2259 * MakePipeTShapeChamfer
2260 * Create a T-shape object with specified caracteristics for the main and
2261 * the incident pipes (radius, width, half-length). A chamfer is created
2262 * on the junction of the pipes.
2263 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2264 * \param theR1 Internal radius of main pipe
2265 * \param theW1 Width of main pipe
2266 * \param theL1 Half-length of main pipe
2267 * \param theR2 Internal radius of incident pipe (R2 < R1)
2268 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2269 * \param theL2 Half-length of incident pipe
2270 * \param theH Height of chamfer.
2271 * \param theW Width of chamfer.
2272 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2273 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2275 //=============================================================================
2276 Handle(TColStd_HSequenceOfTransient)
2277 AdvancedEngine_IOperations::MakePipeTShapeChamfer
2278 (double theR1, double theW1, double theL1,
2279 double theR2, double theW2, double theL2,
2280 double theRL, double theWL, double theLtransL, double theLthinL,
2281 double theRR, double theWR, double theLtransR, double theLthinR,
2282 double theRI, double theWI, double theLtransI, double theLthinI,
2283 double theH, double theW,
2288 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2289 //Add a new shape function with parameters
2290 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2291 if (aFunction.IsNull()) return NULL;
2293 //Check if the function is set correctly
2294 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2296 AdvancedEngine_IPipeTShape aData(aFunction);
2306 aData.SetHexMesh(theHexMesh);
2308 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2309 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2310 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2312 //Compute the resulting value
2315 if (!GetSolver()->ComputeFunction(aFunction)) {
2316 SetErrorCode("TShape driver failed");
2320 catch (Standard_Failure) {
2321 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2322 SetErrorCode(aFail->GetMessageString());
2327 TopoDS_Shape aShapeShape = aShape->GetValue();
2328 TopTools_IndexedMapOfShape anEdgesIndices;
2329 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2330 // Common edges on external cylinders
2331 Handle(GEOM_Object) box_e;
2333 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2336 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2338 box_e->GetLastFunction()->SetDescription("");
2339 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2340 box_e->GetLastFunction()->SetDescription("");
2342 Handle(TColStd_HSequenceOfInteger) edges_e =
2343 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2344 box_e->GetLastFunction()->SetDescription("");
2346 if (edges_e.IsNull() || edges_e->Length() == 0) {
2347 SetErrorCode("External edges not found");
2350 int nbEdgesInChamfer = 0;
2351 std::list<int> theEdges;
2352 for (int i=1; i<=edges_e->Length();i++) {
2353 int edgeID = edges_e->Value(i);
2354 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2355 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2359 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2360 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2361 nbEdgesInChamfer ++;
2362 theEdges.push_back(edgeID);
2366 if (theHexMesh && nbEdgesInChamfer == 1)
2369 Handle(GEOM_Object) aChamfer;
2371 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2373 catch (Standard_Failure) {
2374 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2375 SetErrorCode(aFail->GetMessageString());
2378 if (aChamfer.IsNull()) {
2379 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2382 aChamfer->GetLastFunction()->SetDescription("");
2384 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2385 aFunction->SetValue(aChamferShape);
2389 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2391 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2395 // Add thickness reduction elements
2396 // at the three extremities: Left, Right and Incident
2399 if (isTRL || isTRR || isTRI) {
2400 TopoDS_Shape aResShape =
2401 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2402 theRL, theWL, theLtransL, theLthinL,
2403 theRR, theWR, theLtransR, theLthinR,
2404 theRI, theWI, theLtransI, theLthinI,
2406 aFunction->SetValue(aResShape);
2409 catch (Standard_Failure) {
2410 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2411 SetErrorCode(aFail->GetMessageString());
2415 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2416 aSeq->Append(aShape);
2421 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2422 theH, theW, 0., aSeq, gp_Trsf()))
2426 // Get internal group.
2427 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2428 theRR, theLtransR, theRI, theLtransI,
2433 catch (Standard_Failure) {
2434 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2435 SetErrorCode(aFail->GetMessageString());
2439 //Make a Python command
2440 TCollection_AsciiString anEntry, aListRes("[");
2441 // Iterate over the sequence aSeq
2442 Standard_Integer aNbGroups = aSeq->Length();
2443 Standard_Integer i = 1;
2444 for (; i <= aNbGroups; i++) {
2445 Handle(Standard_Transient) anItem = aSeq->Value(i);
2446 if (anItem.IsNull()) continue;
2447 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2448 if (aGroup.IsNull()) continue;
2449 //Make a Python command
2450 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2451 aListRes += anEntry + ", ";
2453 aListRes.Trunc(aListRes.Length() - 2);
2455 GEOM::TPythonDump pd (aFunction);
2457 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2458 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2459 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2460 << theH << ", " << theW << ", " << theHexMesh;
2462 // thickness reduction
2464 pd << ", theRL=" << theRL << ", theWL=" << theWL
2465 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2467 pd << ", theRR=" << theRR << ", theWR=" << theWR
2468 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2470 pd << ", theRI=" << theRI << ", theWI=" << theWI
2471 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2480 //=============================================================================
2482 * MakePipeTShapeChamferWithPosition
2483 * Create a T-shape object with specified caracteristics for the main and
2484 * the incident pipes (radius, width, half-length). A chamfer is created
2485 * on the junction of the pipes.
2486 * The extremities of the main pipe are located on junctions points P1 and P2.
2487 * The extremity of the incident pipe is located on junction point P3.
2488 * \param theR1 Internal radius of main pipe
2489 * \param theW1 Width of main pipe
2490 * \param theL1 Half-length of main pipe
2491 * \param theR2 Internal radius of incident pipe (R2 < R1)
2492 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2493 * \param theL2 Half-length of incident pipe
2494 * \param theH Height of chamfer.
2495 * \param theW Width of chamfer.
2496 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2497 * \param theP1 1st junction point of main pipe
2498 * \param theP2 2nd junction point of main pipe
2499 * \param theP3 Junction point of incident pipe
2500 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2502 //=============================================================================
2503 Handle(TColStd_HSequenceOfTransient)
2504 AdvancedEngine_IOperations::MakePipeTShapeChamferWithPosition
2505 (double theR1, double theW1, double theL1,
2506 double theR2, double theW2, double theL2,
2507 double theRL, double theWL, double theLtransL, double theLthinL,
2508 double theRR, double theWR, double theLtransR, double theLthinR,
2509 double theRI, double theWI, double theLtransI, double theLthinI,
2510 double theH, double theW,
2512 Handle(GEOM_Object) theP1,
2513 Handle(GEOM_Object) theP2,
2514 Handle(GEOM_Object) theP3)
2518 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2519 //Add a new shape function with parameters
2520 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2521 if (aFunction.IsNull()) return NULL;
2523 //Check if the function is set correctly
2524 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2526 // Check new position
2527 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2531 AdvancedEngine_IPipeTShape aData(aFunction);
2541 aData.SetHexMesh(theHexMesh);
2543 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2544 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2545 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2547 //Compute the resulting value
2550 if (!GetSolver()->ComputeFunction(aFunction)) {
2551 SetErrorCode("TShape driver failed");
2555 catch (Standard_Failure) {
2556 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2557 SetErrorCode(aFail->GetMessageString());
2562 TopoDS_Shape aShapeShape = aShape->GetValue();
2563 TopTools_IndexedMapOfShape anEdgesIndices;
2564 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2565 // Common edges on external cylinders
2566 Handle(GEOM_Object) box_e;
2568 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2571 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2573 box_e->GetLastFunction()->SetDescription("");
2574 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2575 box_e->GetLastFunction()->SetDescription("");
2577 Handle(TColStd_HSequenceOfInteger) edges_e =
2578 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2579 box_e->GetLastFunction()->SetDescription("");
2581 if (edges_e.IsNull() || edges_e->Length() == 0) {
2582 SetErrorCode("External edges not found");
2585 int nbEdgesInChamfer = 0;
2586 std::list<int> theEdges;
2587 for (int i=1; i<=edges_e->Length();i++) {
2588 int edgeID = edges_e->Value(i);
2589 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2590 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2592 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2593 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2594 nbEdgesInChamfer ++;
2595 theEdges.push_back(edgeID);
2599 if (theHexMesh && nbEdgesInChamfer == 1)
2602 Handle(GEOM_Object) aChamfer;
2604 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2606 catch (Standard_Failure) {
2607 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2608 SetErrorCode(aFail->GetMessageString());
2611 if (aChamfer.IsNull()) {
2612 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2615 aChamfer->GetLastFunction()->SetDescription("");
2617 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2618 aFunction->SetValue(aChamferShape);
2622 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2624 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2628 // Add thickness reduction elements
2629 // at the three extremities: Left, Right and Incident
2632 if (isTRL || isTRR || isTRI) {
2633 TopoDS_Shape aResShape =
2634 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2635 theRL, theWL, theLtransL, theLthinL,
2636 theRR, theWR, theLtransR, theLthinR,
2637 theRI, theWI, theLtransI, theLthinI,
2639 aFunction->SetValue(aResShape);
2642 catch (Standard_Failure) {
2643 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2644 SetErrorCode(aFail->GetMessageString());
2649 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2650 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
2651 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2652 aFunction->SetValue(aTrsf_Shape);
2654 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2655 aSeq->Append(aShape);
2660 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2661 theH, theW, 0., aSeq, aTrsf))
2665 // Get internal group.
2666 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2667 theRR, theLtransR, theRI, theLtransI,
2672 catch (Standard_Failure) {
2673 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2674 SetErrorCode(aFail->GetMessageString());
2678 //Make a Python command
2679 TCollection_AsciiString anEntry, aListRes("[");
2680 // Iterate over the sequence aSeq
2681 Standard_Integer aNbGroups = aSeq->Length();
2682 Standard_Integer i = 1;
2683 for (; i <= aNbGroups; i++) {
2684 Handle(Standard_Transient) anItem = aSeq->Value(i);
2685 if (anItem.IsNull()) continue;
2686 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2687 if (aGroup.IsNull()) continue;
2688 //Make a Python command
2689 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2690 aListRes += anEntry + ", ";
2692 aListRes.Trunc(aListRes.Length() - 2);
2694 GEOM::TPythonDump pd (aFunction);
2696 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2697 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2698 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2699 << theH << ", " << theW << ", " << theHexMesh << ", "
2700 << theP1 << ", " << theP2 << ", " << theP3;
2702 // thickness reduction
2704 pd << ", theRL=" << theRL << ", theWL=" << theWL
2705 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2707 pd << ", theRR=" << theRR << ", theWR=" << theWR
2708 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2710 pd << ", theRI=" << theRI << ", theWI=" << theWI
2711 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2720 //=============================================================================
2722 * MakePipeTShapeFillet
2723 * Create a T-shape object with specified caracteristics for the main and
2724 * the incident pipes (radius, width, half-length). A fillet is created
2725 * on the junction of the pipes.
2726 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2727 * \param theR1 Internal radius of main pipe
2728 * \param theW1 Width of main pipe
2729 * \param theL1 Half-length of main pipe
2730 * \param theR2 Internal radius of incident pipe (R2 < R1)
2731 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2732 * \param theL2 Half-length of incident pipe
2733 * \param theRF Radius of curvature of fillet.
2734 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2735 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2737 //=============================================================================
2738 Handle(TColStd_HSequenceOfTransient)
2739 AdvancedEngine_IOperations::MakePipeTShapeFillet
2740 (double theR1, double theW1, double theL1,
2741 double theR2, double theW2, double theL2,
2742 double theRL, double theWL, double theLtransL, double theLthinL,
2743 double theRR, double theWR, double theLtransR, double theLthinR,
2744 double theRI, double theWI, double theLtransI, double theLthinI,
2745 double theRF, bool theHexMesh)
2749 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2750 //Add a new shape function with parameters
2751 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2752 if (aFunction.IsNull()) return NULL;
2754 //Check if the function is set correctly
2755 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2757 AdvancedEngine_IPipeTShape aData(aFunction);
2766 aData.SetHexMesh(theHexMesh);
2768 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2769 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2770 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2772 //Compute the resulting value
2775 if (!GetSolver()->ComputeFunction(aFunction)) {
2776 SetErrorCode("TShape driver failed");
2780 catch (Standard_Failure) {
2781 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2782 SetErrorCode(aFail->GetMessageString());
2787 TopoDS_Shape aShapeShape = aShape->GetValue();
2788 TopTools_IndexedMapOfShape anEdgesIndices;
2789 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2790 // Common edges on external cylinders
2791 Handle(GEOM_Object) box_e;
2793 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2796 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2798 box_e->GetLastFunction()->SetDescription("");
2799 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2800 box_e->GetLastFunction()->SetDescription("");
2802 Handle(TColStd_HSequenceOfInteger) edges_e =
2803 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2804 box_e->GetLastFunction()->SetDescription("");
2806 if (edges_e.IsNull() || edges_e->Length() == 0) {
2807 SetErrorCode("External edges not found");
2810 int nbEdgesInFillet = 0;
2811 std::list<int> theEdges;
2812 for (int i=1; i<=edges_e->Length();i++) {
2813 int edgeID = edges_e->Value(i);
2814 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2815 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2817 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2818 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2820 theEdges.push_back(edgeID);
2824 if (theHexMesh && nbEdgesInFillet == 1)
2828 Handle(GEOM_Object) aFillet;
2830 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2832 catch (Standard_Failure) {
2833 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2834 SetErrorCode(aFail->GetMessageString());
2837 if (aFillet.IsNull()) {
2838 //SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
2839 SetErrorCode(myLocalOperations->GetErrorCode());
2842 aFillet->GetLastFunction()->SetDescription("");
2844 TopoDS_Shape aFilletShape = aFillet->GetValue();
2845 aFunction->SetValue(aFilletShape);
2848 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (1)
2849 // the following block, when enabled, leads to partitioning problems
2851 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (1)
2852 // BEGIN: Limit tolerances (debug)
2853 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
2854 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
2855 aShape->GetLastFunction()->SetValue(aCorr1Shape);
2856 aCorr1->GetLastFunction()->SetDescription("");
2857 // END: Limit tolerances (debug)
2858 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (2)
2860 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (2)
2863 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2865 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2869 // Add thickness reduction elements
2870 // at the three extremities: Left, Right and Incident
2873 if (isTRL || isTRR || isTRI) {
2874 TopoDS_Shape aResShape =
2875 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2876 theRL, theWL, theLtransL, theLthinL,
2877 theRR, theWR, theLtransR, theLthinR,
2878 theRI, theWI, theLtransI, theLthinI,
2880 aFunction->SetValue(aResShape);
2883 catch (Standard_Failure) {
2884 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2885 SetErrorCode(aFail->GetMessageString());
2889 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2890 aSeq->Append(aShape);
2895 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
2896 0., 0., theRF, aSeq, gp_Trsf()))
2900 // Get internal group.
2901 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2902 theRR, theLtransR, theRI, theLtransI,
2907 catch (Standard_Failure) {
2908 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2909 SetErrorCode(aFail->GetMessageString());
2913 //Make a Python command
2914 TCollection_AsciiString anEntry, aListRes("[");
2915 // Iterate over the sequence aSeq
2916 Standard_Integer aNbGroups = aSeq->Length();
2917 Standard_Integer i = 1;
2918 for (; i <= aNbGroups; i++) {
2919 Handle(Standard_Transient) anItem = aSeq->Value(i);
2920 if (anItem.IsNull()) continue;
2921 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2922 if (aGroup.IsNull()) continue;
2923 //Make a Python command
2924 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2925 aListRes += anEntry + ", ";
2927 aListRes.Trunc(aListRes.Length() - 2);
2929 GEOM::TPythonDump pd (aFunction);
2931 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
2932 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2933 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2934 << theRF << ", " << theHexMesh;
2936 // thickness reduction
2938 pd << ", theRL=" << theRL << ", theWL=" << theWL
2939 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2941 pd << ", theRR=" << theRR << ", theWR=" << theWR
2942 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2944 pd << ", theRI=" << theRI << ", theWI=" << theWI
2945 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2954 //=============================================================================
2956 * MakePipeTShapeFilletWithPosition
2957 * \brief Create a T-shape object with specified caracteristics for the main and
2958 * the incident pipes (radius, width, half-length). A fillet is created
2959 * on the junction of the pipes.
2960 * The extremities of the main pipe are located on junctions points P1 and P2.
2961 * The extremity of the incident pipe is located on junction point P3.
2962 * \param theR1 Internal radius of main pipe
2963 * \param theW1 Width of main pipe
2964 * \param theL1 Half-length of main pipe
2965 * \param theR2 Internal radius of incident pipe (R2 < R1)
2966 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2967 * \param theL2 Half-length of incident pipe
2968 * \param theRF Radius of curvature of fillet
2969 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2970 * \param theP1 1st junction point of main pipe
2971 * \param theP2 2nd junction point of main pipe
2972 * \param theP3 Junction point of incident pipe
2973 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2975 //=============================================================================
2976 Handle(TColStd_HSequenceOfTransient)
2977 AdvancedEngine_IOperations::MakePipeTShapeFilletWithPosition
2978 (double theR1, double theW1, double theL1,
2979 double theR2, double theW2, double theL2,
2980 double theRL, double theWL, double theLtransL, double theLthinL,
2981 double theRR, double theWR, double theLtransR, double theLthinR,
2982 double theRI, double theWI, double theLtransI, double theLthinI,
2983 double theRF, bool theHexMesh,
2984 Handle(GEOM_Object) theP1,
2985 Handle(GEOM_Object) theP2,
2986 Handle(GEOM_Object) theP3)
2990 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2991 //Add a new shape function with parameters
2992 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2993 if (aFunction.IsNull()) return NULL;
2995 //Check if the function is set correctly
2996 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2998 // Check new position
2999 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
3003 AdvancedEngine_IPipeTShape aData(aFunction);
3012 aData.SetHexMesh(theHexMesh);
3014 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
3015 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
3016 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
3018 //Compute the resulting value
3021 if (!GetSolver()->ComputeFunction(aFunction)) {
3022 SetErrorCode("TShape driver failed");
3026 catch (Standard_Failure) {
3027 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3028 SetErrorCode(aFail->GetMessageString());
3033 TopoDS_Shape aShapeShape = aShape->GetValue();
3034 TopTools_IndexedMapOfShape anEdgesIndices;
3035 TopExp::MapShapes(aShapeShape, anEdgesIndices);
3036 // Common edges on external cylinders
3037 Handle(GEOM_Object) box_e;
3039 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
3042 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
3044 box_e->GetLastFunction()->SetDescription("");
3045 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
3046 box_e->GetLastFunction()->SetDescription("");
3048 Handle(TColStd_HSequenceOfInteger) edges_e =
3049 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
3050 box_e->GetLastFunction()->SetDescription("");
3052 if (edges_e.IsNull() || edges_e->Length() == 0) {
3053 SetErrorCode("External edges not found");
3056 int nbEdgesInFillet = 0;
3057 std::list<int> theEdges;
3058 for (int i=1; i<=edges_e->Length();i++) {
3059 int edgeID = edges_e->Value(i);
3060 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
3061 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
3063 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
3064 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
3066 theEdges.push_back(edgeID);
3070 if (theHexMesh && nbEdgesInFillet == 1)
3074 Handle(GEOM_Object) aFillet;
3076 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
3078 catch (Standard_Failure) {
3079 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3080 SetErrorCode(aFail->GetMessageString());
3083 if (aFillet.IsNull()) {
3084 SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
3087 aFillet->GetLastFunction()->SetDescription("");
3089 TopoDS_Shape aFilletShape = aFillet->GetValue();
3090 aFunction->SetValue(aFilletShape);
3093 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (3)
3094 // the following block, when enabled, leads to partitioning problems
3096 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (3)
3097 // BEGIN: Limit tolerances (debug)
3098 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
3099 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
3100 aShape->GetLastFunction()->SetValue(aCorr1Shape);
3101 aCorr1->GetLastFunction()->SetDescription("");
3102 // END: Limit tolerances (debug)
3103 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (4)
3105 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (4)
3108 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
3110 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
3114 // Add thickness reduction elements
3115 // at the three extremities: Left, Right and Incident
3118 if (isTRL || isTRR || isTRI) {
3119 TopoDS_Shape aResShape =
3120 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
3121 theRL, theWL, theLtransL, theLthinL,
3122 theRR, theWR, theLtransR, theLthinR,
3123 theRI, theWI, theLtransI, theLthinI,
3125 aFunction->SetValue(aResShape);
3128 catch (Standard_Failure) {
3129 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3130 SetErrorCode(aFail->GetMessageString());
3135 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
3136 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
3137 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
3138 aFunction->SetValue(aTrsf_Shape);
3140 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
3141 aSeq->Append(aShape);
3146 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
3147 0., 0., theRF, aSeq, aTrsf))
3151 // Get internal group.
3152 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
3153 theRR, theLtransR, theRI, theLtransI,
3158 catch (Standard_Failure) {
3159 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3160 SetErrorCode(aFail->GetMessageString());
3164 //Make a Python command
3165 TCollection_AsciiString anEntry, aListRes("[");
3166 // Iterate over the sequence aSeq
3167 Standard_Integer aNbGroups = aSeq->Length();
3168 Standard_Integer i = 1;
3169 for (; i <= aNbGroups; i++) {
3170 Handle(Standard_Transient) anItem = aSeq->Value(i);
3171 if (anItem.IsNull()) continue;
3172 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
3173 if (aGroup.IsNull()) continue;
3174 //Make a Python command
3175 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
3176 aListRes += anEntry + ", ";
3178 aListRes.Trunc(aListRes.Length() - 2);
3180 GEOM::TPythonDump pd (aFunction);
3182 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
3183 << theR1 << ", " << theW1 << ", " << theL1 << ", "
3184 << theR2 << ", " << theW2 << ", " << theL2 << ", "
3185 << theRF << ", " << theHexMesh << ", "
3186 << theP1 << ", " << theP2 << ", " << theP3;
3188 // thickness reduction
3190 pd << ", theRL=" << theRL << ", theWL=" << theWL
3191 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
3193 pd << ", theRR=" << theRR << ", theWR=" << theWR
3194 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
3196 pd << ", theRI=" << theRI << ", theWI=" << theWI
3197 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
3206 //=============================================================================
3208 * This function allows to create a disk already divided into blocks. It can be
3209 * used to create divided pipes for later meshing in hexaedra.
3210 * \param theR Radius of the disk
3211 * \param theRatio Relative size of the central square diagonal against the disk diameter
3212 * \param theOrientation Plane on which the disk will be built
3213 * \param thePattern The division pattern of the disk (hexagon or square in the center)
3214 * \return New GEOM_Object, containing the created shape.
3216 //=============================================================================
3217 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDisk (double theR, double theRatio,
3218 int theOrientation, int thePattern)
3222 if (theOrientation != 1 &&
3223 theOrientation != 2 &&
3224 theOrientation != 3)
3226 SetErrorCode("theOrientation must be 1(=OXY), 2(=OYZ) or 3(=OZX)");
3230 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3232 //Add a new shape function with parameters
3233 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_RATIO);
3234 if (aFunction.IsNull()) return NULL;
3236 //Check if the function is set correctly
3237 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3239 AdvancedEngine_IDividedDisk aData (aFunction);
3242 aData.SetRatio(theRatio);
3243 aData.SetOrientation(theOrientation);
3244 aData.SetType(thePattern);
3246 //Compute the resulting value
3249 if (!GetSolver()->ComputeFunction(aFunction)) {
3250 SetErrorCode("DividedDisk driver failed");
3254 catch (Standard_Failure) {
3255 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3256 SetErrorCode(aFail->GetMessageString());
3260 std::string aPatternStr;
3265 aPatternStr = "GEOM.SQUARE";
3268 aPatternStr = "GEOM.HEXAGON";
3272 //Make a Python command
3273 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDisk(" << theR << ", " << theOrientation << ", " << aPatternStr.c_str() << ")";
3280 //=============================================================================
3282 * This function allows to create a disk already divided into blocks. It can be
3283 * used to create divided pipes for later meshing in hexaedra.
3284 * \param theR Radius of the disk
3285 * \param theRatio Relative size of the central square diagonal against the disk diameter
3286 * \return New GEOM_Object, containing the created shape.
3288 //=============================================================================
3289 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDiskPntVecR (Handle(GEOM_Object) thePnt,
3290 Handle(GEOM_Object) theVec,
3298 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3300 //Add a new shape function with parameters
3301 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_VECTOR_PNT);
3302 if (aFunction.IsNull()) return NULL;
3304 //Check if the function is set correctly
3305 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3307 AdvancedEngine_IDividedDisk aData (aFunction);
3309 Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
3310 Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
3312 if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
3314 aData.SetCenter(aRefPnt);
3315 aData.SetVector(aRefVec);
3318 aData.SetRatio(theRatio);
3319 aData.SetType(thePattern);
3321 //Compute the resulting value
3324 if (!GetSolver()->ComputeFunction(aFunction)) {
3325 SetErrorCode("DividedDisk driver failed");
3329 catch (Standard_Failure) {
3330 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3331 SetErrorCode(aFail->GetMessageString());
3335 std::string aPatternStr;
3340 aPatternStr = "GEOM.SQUARE";
3343 aPatternStr = "GEOM.HEXAGON";
3348 //Make a Python command
3349 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDiskPntVecR(" << thePnt << ", " << theVec << ", " << theR << ", " << aPatternStr.c_str() << ")";
3356 //=============================================================================
3358 * Builds a cylinder prepared for hexa meshes
3359 * \param theR Radius of the cylinder
3360 * \param theH Height of the cylinder
3361 * \return New GEOM_Object, containing the created shape.
3363 //=============================================================================
3364 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedCylinder (double theR,
3371 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDCYLINDER);
3373 Handle(GEOM_Object) aBaseShape = MakeDividedDisk(theR, 67.0, 1, thePattern);
3374 aBaseShape->GetLastFunction()->SetDescription(""); // Erase dump of MakeDividedDisk
3376 aShape = my3DPrimOperations->MakePrismDXDYDZ(aBaseShape,0.0,0.0,theH, -1.0);
3378 Handle(GEOM_Function) aFunction = aShape->GetLastFunction();
3379 aFunction->SetDescription(""); // Erase dump of MakePrismDXDYDZ
3380 aShape->SetType(GEOM_DIVIDEDCYLINDER);
3382 std::string aPatternStr;
3387 aPatternStr = "GEOM.SQUARE";
3390 aPatternStr = "GEOM.HEXAGON";
3394 //Make a Python command
3395 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedCylinder(" << theR << ", " << theH << ", " << aPatternStr.c_str() << ")";
3401 //=============================================================================
3403 * Create a smoothing surface from a set of points
3404 * \param thelPoints list of points or compounds of points
3405 * \param theNbMax maximum number of Bezier pieces in the resulting surface.
3406 * \param theDegMax maximum degree of the resulting BSpline surface
3407 * \param theDMax specifies maximum value of the GeomPlate_PlateG0Criterion criterion.
3408 * \return New GEOM_Object, containing the created shape.
3410 //=============================================================================
3411 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeSmoothingSurface (std::list<Handle(GEOM_Object)> thelPoints,
3419 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_SMOOTHINGSURFACE);
3421 //Add a new shape function with parameters
3422 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_SmoothingSurfaceDriver::GetID(), SMOOTHINGSURFACE_LPOINTS);
3423 if (aFunction.IsNull()) return NULL;
3425 //Check if the function is set correctly
3426 if (aFunction->GetDriverGUID() != AdvancedEngine_SmoothingSurfaceDriver::GetID()) return NULL;
3428 AdvancedEngine_ISmoothingSurface aData (aFunction);
3430 int aLen = thelPoints.size();
3431 aData.SetLength(aLen);
3433 std::list<Handle(GEOM_Object)>::iterator it = thelPoints.begin();
3434 for (; it != thelPoints.end(); it++, ind++) {
3435 Handle(GEOM_Function) aRefObj = (*it)->GetLastFunction();
3436 if (aRefObj.IsNull()) {
3437 SetErrorCode("NULL point or compound for bSplineFaceShape");
3440 aData.SetPntOrComp(ind, aRefObj);
3443 aData.SetNbMax(theNbMax);
3444 aData.SetDegMax(theDegMax);
3445 aData.SetDMax(theDMax);
3447 //Compute the resulting value
3450 if (!GetSolver()->ComputeFunction(aFunction)) {
3451 SetErrorCode("SmoothingSurface driver failed");
3455 catch (Standard_Failure) {
3456 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3457 SetErrorCode(aFail->GetMessageString());
3461 //Make a Python command
3462 GEOM::TPythonDump pd (aFunction);
3463 pd << aShape << " = geompy.MakeSmoothingSurface([";
3464 it = thelPoints.begin();
3466 while (it != thelPoints.end()) {
3467 pd << ", " << (*it++);
3471 << theDegMax << ", "