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;
1152 #if OCC_VERSION_LARGE > 0x06010000
1155 Handle(GEOM_Object) Vector_Z = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1156 Vector_Z->GetLastFunction()->SetDescription("");
1159 double aSize = 2*(theL1 + theL2);
1160 double aR1Ext = theR1 + theW1;
1161 double aR2Ext = theR2 + theW2;
1162 double theVertCylinderRadius = aR2Ext + theW + theRF;
1163 double theHoriCylinderRadius = aR1Ext + theH + theRF;
1165 // Common edges on internal cylinder
1166 Handle(GEOM_Object) box_i = my3DPrimOperations->MakeBoxDXDYDZ(theR2, theR2, theR1);
1167 box_i->GetLastFunction()->SetDescription("");
1168 box_i = myTransformOperations->TranslateDXDYDZ(box_i, -theR2, -theR2, 0);
1169 box_i->GetLastFunction()->SetDescription("");
1171 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1172 TCollection_AsciiString theDesc = aFunction->GetDescription();
1173 Handle(TColStd_HSequenceOfTransient) edges_i =
1174 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1175 // Recover previous description to get rid of Propagate dump
1176 aFunction->SetDescription(theDesc);
1177 if (edges_i.IsNull() || edges_i->Length() == 0) {
1178 SetErrorCode("Internal edges not found");
1181 for (int i=1; i<=edges_i->Length();i++) {
1182 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_i->Value(i));
1183 anObj->GetLastFunction()->SetDescription("");
1185 arete_intersect_int = Handle(GEOM_Object)::DownCast(edges_i->Value(1));
1187 // search for vertices located on both internal pipes
1188 aFunction = theShape->GetLastFunction();
1189 theDesc = aFunction->GetDescription();
1190 Handle(TColStd_HSequenceOfTransient) vertices_i =
1191 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1192 // Recover previous description to get rid of Propagate dump
1193 aFunction->SetDescription(theDesc);
1194 if (vertices_i.IsNull() || vertices_i->Length() == 0) {
1195 SetErrorCode("Internal vertices not found");
1199 double d1min = theR2+theW2, d2min=theR2+theW2;
1200 for (int i = 1; i <= vertices_i->Length(); i++) {
1201 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_i->Value(i));
1202 v->GetLastFunction()->SetDescription("");
1203 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1204 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1205 if (Abs(aP.X()) <= Precision::Confusion()) {
1206 if (Abs(aP.Y()) < d1min) {
1208 d1min = Abs(aP.Y());
1210 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1211 if (Abs(aP.X()) < d2min) {
1213 d2min = Abs(aP.X());
1217 if (vi1.IsNull() || vi2.IsNull()) {
1218 SetErrorCode("Cannot find internal intersection vertices");
1222 std::list<Handle(GEOM_Object)> theShapes;
1225 Handle(GEOM_Object) ve1, ve2;
1226 TopoDS_Vertex vertex1, vertex2;
1228 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ(aR2Ext, aR2Ext, aR1Ext);
1229 box_e->GetLastFunction()->SetDescription("");
1230 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -aR2Ext, -aR2Ext, 0);
1231 box_e->GetLastFunction()->SetDescription("");
1233 // search for vertices located on both external pipes
1234 aFunction = theShape->GetLastFunction();
1235 theDesc = aFunction->GetDescription();
1236 Handle(TColStd_HSequenceOfTransient) vertices_e =
1237 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1238 // Recover previous description to get rid of Propagate dump
1239 aFunction->SetDescription(theDesc);
1240 if (vertices_e.IsNull() || vertices_e->Length() == 0) {
1241 SetErrorCode("External vertices not found");
1245 double d1max = 0, d2max = 0;
1246 for (int i = 1; i <= vertices_e->Length(); i++) {
1247 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_e->Value(i));
1248 v->GetLastFunction()->SetDescription("");
1249 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1250 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1251 if (Abs(aP.X()) <= Precision::Confusion()) {
1252 if (Abs(aP.Y()) > d1max) {
1255 d1max = Abs(aP.Y());
1257 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1258 if (Abs(aP.X()) > d2max) {
1261 d2max = Abs(aP.X());
1265 if (ve1.IsNull() || ve2.IsNull()) {
1266 SetErrorCode("Cannot find external intersection vertices");
1269 Handle(GEOM_Object) edge_e1, edge_e2;
1271 // Common edges on external cylinder
1272 aFunction = theShape->GetLastFunction();
1273 theDesc = aFunction->GetDescription();
1274 Handle(TColStd_HSequenceOfTransient) edges_e =
1275 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1276 // Recover previous description to get rid of Propagate dump
1277 aFunction->SetDescription(theDesc);
1278 if (edges_e.IsNull() || edges_e->Length() == 0) {
1279 SetErrorCode("External edges not found");
1282 ShapeAnalysis_Edge sae;
1283 for (int i=1; i<=edges_e->Length();i++) {
1284 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
1285 anObj->GetLastFunction()->SetDescription("");
1286 TopoDS_Edge anEdge = TopoDS::Edge(anObj->GetValue());
1287 if ( !anEdge.IsNull() &&
1288 (sae.FirstVertex(anEdge).IsSame(vertex1) || sae.LastVertex(anEdge).IsSame(vertex1)) &&
1289 (sae.FirstVertex(anEdge).IsSame(vertex2) || sae.LastVertex(anEdge).IsSame(vertex2))) {
1290 arete_intersect_ext = anObj;
1294 edge_e1 = myBasicOperations->MakeLineTwoPnt(ve1, vi1);
1295 if (edge_e1.IsNull()) {
1296 SetErrorCode("Edge 1 could not be built");
1300 edge_e2 = myBasicOperations->MakeLineTwoPnt(ve2, vi2);
1301 if (edge_e2.IsNull()) {
1302 SetErrorCode("Edge 2 could not be built");
1306 edge_e1->GetLastFunction()->SetDescription("");
1307 edge_e2->GetLastFunction()->SetDescription("");
1309 std::list<Handle(GEOM_Object)> edge_e_elist;
1310 edge_e_elist.push_back(arete_intersect_int);
1311 edge_e_elist.push_back(edge_e1);
1312 edge_e_elist.push_back(arete_intersect_ext);
1313 edge_e_elist.push_back(edge_e2);
1314 wire_t = myShapesOperations->MakeWire(edge_e_elist, 1e-7);
1315 if (wire_t.IsNull()) {
1316 SetErrorCode("Impossible to build wire");
1319 wire_t->GetLastFunction()->SetDescription("");
1320 face_t = myShapesOperations->MakeFace(wire_t, false);
1321 if (face_t.IsNull()) {
1322 SetErrorCode("Impossible to build face");
1325 face_t->GetLastFunction()->SetDescription("");
1327 theShapes.push_back(theShape);
1328 theShapes.push_back(vi1);
1329 theShapes.push_back(vi2);
1330 theShapes.push_back(ve1);
1331 theShapes.push_back(ve2);
1332 theShapes.push_back(edge_e1);
1333 theShapes.push_back(edge_e2);
1334 theShapes.push_back(wire_t);
1335 theShapes.push_back(face_t);
1338 Handle(GEOM_Object) P1, P2, P3, P4, P5, P6;
1339 int idP1, idP2, idP3, idP4;
1342 std::vector<int> LX;
1343 std::vector<int> LY;
1344 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ
1345 (theVertCylinderRadius, theVertCylinderRadius, theHoriCylinderRadius);
1346 box_e->GetLastFunction()->SetDescription("");
1347 box_e = myTransformOperations->TranslateDXDYDZ
1348 (box_e, -theVertCylinderRadius, -theVertCylinderRadius, 0);
1349 box_e->GetLastFunction()->SetDescription("");
1351 aFunction = theShape->GetLastFunction();
1352 theDesc = aFunction->GetDescription();
1353 Handle(TColStd_HSequenceOfTransient) extremVertices =
1354 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1355 // Recover previous description to get rid of Propagate dump
1356 aFunction->SetDescription(theDesc);
1358 if (extremVertices.IsNull() || extremVertices->Length() == 0) {
1360 SetErrorCode("Vertices on chamfer not found");
1362 SetErrorCode("Vertices on fillet not found");
1366 theShapes.push_back(theShape);
1367 theShapes.push_back(box_e);
1368 if (extremVertices->Length() != 6) {
1369 // for (int i=1; i<=extremVertices->Length(); i++){
1370 // theShapes.push_back(Handle(GEOM_Object)::DownCast(extremVertices->Value(i)));
1372 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1373 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1374 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1375 SetErrorCode("Bad number of vertices on chamfer found");
1379 for (int i=1; i<=extremVertices->Length(); i++){
1380 Handle(GEOM_Object) aV = Handle(GEOM_Object)::DownCast(extremVertices->Value(i));
1381 aV->GetLastFunction()->SetDescription("");
1382 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aV->GetValue()));
1384 if (Abs(aP.X()) <= Precision::Confusion()) {
1385 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
1387 if (aP.Z()-ZX > Precision::Confusion()) {
1394 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
1396 if (aP.Z() - ZY > Precision::Confusion()) {
1407 if (LX.at(0) == PZX)
1410 if (LY.at(0) == PZY)
1413 P1 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP1));
1414 P2 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP2));
1415 P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
1416 P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4));
1418 Handle(GEOM_Object) Cote_1 = myBasicOperations->MakeLineTwoPnt(P1, vi1);
1419 if (Cote_1.IsNull()) {
1420 SetErrorCode("Impossible to build edge in thickness");
1423 Cote_1->GetLastFunction()->SetDescription("");
1425 Handle(GEOM_Object) Cote_2 = myBasicOperations->MakeLineTwoPnt(vi2, P3);
1426 if (Cote_2.IsNull()) {
1427 SetErrorCode("Impossible to build edge in thickness");
1430 Cote_2->GetLastFunction()->SetDescription("");
1432 // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
1433 // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
1434 // std::cerr << "Getting chamfer edge on main pipe" << std::endl;
1435 Handle(GEOM_Object) edge_chan_princ = myBlocksOperations->GetEdge(theShape, P1, P3);
1436 if (edge_chan_princ.IsNull()) {
1437 SetErrorCode("Impossible to find edge on main pipe");
1440 edge_chan_princ->GetLastFunction()->SetDescription("");
1442 Handle(GEOM_Object) edge_chan_inc = myBlocksOperations->GetEdge(theShape, P2, P4);
1443 if (edge_chan_inc.IsNull()) {
1444 SetErrorCode("Impossible to find edge on incident pipe");
1447 edge_chan_inc->GetLastFunction()->SetDescription("");
1449 std::list<Handle(GEOM_Object)> edgeList1;
1450 edgeList1.push_back(edge_chan_princ);
1451 edgeList1.push_back(Cote_1);
1452 edgeList1.push_back(arete_intersect_int);
1453 edgeList1.push_back(Cote_2);
1455 // std::cerr << "Creating wire 1" << std::endl;
1456 wire_t = myShapesOperations->MakeWire(edgeList1, 1e-7);
1457 if (wire_t.IsNull()) {
1458 SetErrorCode("Impossible to build wire");
1461 wire_t->GetLastFunction()->SetDescription("");
1463 // std::cerr << "Creating face 1" << std::endl;
1464 face_t = myShapesOperations->MakeFace(wire_t, false);
1465 if (face_t.IsNull()) {
1466 SetErrorCode("Impossible to build face");
1469 face_t->GetLastFunction()->SetDescription("");
1470 theShapes.push_back(face_t);
1472 gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(P2->GetValue()));
1473 gp_Pnt aP5 = BRep_Tool::Pnt(TopoDS::Vertex(vi1->GetValue()));
1474 double deltaZ = aP2.Z() - aP5.Z();
1475 // std::cerr << "Creating new point from vi1 with deltaZ = " << deltaZ << std::endl;
1476 Handle(GEOM_Object) P5bis = myTransformOperations->TranslateDXDYDZCopy(vi1, 0, 0, deltaZ);
1477 if (P5bis.IsNull()) {
1478 SetErrorCode("Impossible to translate vertex");
1481 P5bis->GetLastFunction()->SetDescription("");
1483 gp_Pnt aP4 = BRep_Tool::Pnt(TopoDS::Vertex(P4->GetValue()));
1484 gp_Pnt aP6 = BRep_Tool::Pnt(TopoDS::Vertex(vi2->GetValue()));
1485 deltaZ = aP4.Z() - aP6.Z();
1486 // std::cerr << "Creating new point from vi2 with deltaZ = " << deltaZ << std::endl;
1487 Handle(GEOM_Object) P6bis = myTransformOperations->TranslateDXDYDZCopy(vi2, 0, 0, deltaZ);
1488 if (P6bis.IsNull()) {
1489 SetErrorCode("Impossible to translate vertex");
1492 P6bis->GetLastFunction()->SetDescription("");
1494 // std::cerr << "Creating new line 1 from 2 previous points" << std::endl;
1495 Handle(GEOM_Object) Cote_3 = myBasicOperations->MakeLineTwoPnt(P5bis, P2);
1496 if (Cote_3.IsNull()) {
1497 SetErrorCode("Impossible to build edge in thickness");
1500 Cote_3->GetLastFunction()->SetDescription("");
1502 // std::cerr << "Creating new line 2 from 2 previous points" << std::endl;
1503 Handle(GEOM_Object) Cote_4 = myBasicOperations->MakeLineTwoPnt(P6bis, P4);
1504 if (Cote_4.IsNull()) {
1505 SetErrorCode("Impossible to build edge in thickness");
1508 Cote_4->GetLastFunction()->SetDescription("");
1510 // std::cerr << "Creating new line 3 from 2 previous points" << std::endl;
1511 Handle(GEOM_Object) Cote_5 = myBasicOperations->MakeLineTwoPnt(P5bis, P6bis);
1512 if (Cote_4.IsNull()) {
1513 SetErrorCode("Impossible to build edge in thickness");
1516 Cote_5->GetLastFunction()->SetDescription("");
1518 //std::list<Handle(GEOM_Object)> edgeList2;
1519 //edgeList2.push_back(edge_chan_inc);
1520 //edgeList2.push_back(Cote_3);
1521 //edgeList2.push_back(Cote_5);
1522 //edgeList2.push_back(Cote_4);
1523 // std::cerr << "Creating wire 2" << std::endl;
1524 //wire_t2 = myShapesOperations->MakeWire(edgeList2, 1e-7);
1525 //if (wire_t2.IsNull()) {
1526 // SetErrorCode("Impossible to build wire");
1529 //wire_t2->GetLastFunction()->SetDescription("");
1530 // std::cerr << "Creating face 2" << std::endl;
1531 //face_t2 = myShapesOperations->MakeFace(wire_t2, false);
1533 // Mantis issue 0021682
1534 face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - (theR2 + theW2));
1535 //face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - 2.0*theR2);
1536 if (face_t2.IsNull()) {
1537 SetErrorCode("Impossible to build face");
1540 face_t2->GetLastFunction()->SetDescription("");
1541 theShapes.push_back(face_t2);
1545 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1546 Handle(GEOM_Object) aVZ = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1547 Handle(GEOM_Object) aVXZ = myBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
1548 Handle(GEOM_Object) aPlnOZ = myBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
1549 Handle(GEOM_Object) aPlnOXZ = myBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
1550 aP0->GetLastFunction()->SetDescription("");
1551 aVZ->GetLastFunction()->SetDescription("");
1552 aVXZ->GetLastFunction()->SetDescription("");
1553 aPlnOZ->GetLastFunction()->SetDescription("");
1554 aPlnOXZ->GetLastFunction()->SetDescription("");
1555 theShapes.push_back(aPlnOZ);
1556 theShapes.push_back(aPlnOXZ);
1559 Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
1560 Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
1561 Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
1562 Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
1563 Handle(TColStd_HArray1OfInteger) theMaterials;
1565 partitionShapes->Append(theShape);
1566 theTools->Append(aPlnOZ);
1567 if (Abs(aR1Ext - aR2Ext) > Precision::Confusion())
1568 theTools->Append(aPlnOXZ);
1569 theTools->Append(face_t);
1571 theTools->Append(face_t2);
1573 Te3 = myBooleanOperations->MakePartition
1574 (partitionShapes, theTools, theKeepInside, theRemoveInside,
1575 TopAbs_SOLID, false, theMaterials, 0, false, Standard_False);
1577 SetErrorCode("Impossible to build partition of TShape");
1580 Te3->GetLastFunction()->SetDescription("");
1582 // Last verification: result should be a block
1583 std::list<GEOMImpl_IBlocksOperations::BCError> errList;
1584 if (!myBlocksOperations->CheckCompoundOfBlocks(Te3,errList)) {
1585 SetErrorCode("TShape is not a compound of block");
1589 // // BEGIN Compound of created shapes - Only for debug purpose
1590 // theShapes.clear();
1591 // theShapes.push_back(theShape);
1592 // theShapes.push_back(aPlnOZ);
1593 // if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
1594 // theShapes.push_back(aPlnOXZ);
1595 // theShapes.push_back(face_t);
1597 // theShapes.push_back(face_t2);
1599 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1600 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1601 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1602 // // END Compound of created shapes - Only for debug purpose
1604 TopoDS_Shape aShape = Te3->GetValue();
1605 theShape->GetLastFunction()->SetValue(aShape);
1607 catch (Standard_Failure) {
1608 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1609 SetErrorCode(aFail->GetMessageString());
1617 // Mirror and glue faces
1618 bool AdvancedEngine_IOperations::MakePipeTShapeMirrorAndGlue(Handle(GEOM_Object) theShape,
1619 double theR1, double theW1, double theL1,
1620 double theR2, double theW2, double theL2)
1625 double aSize = 2*(theL1 + theL2);
1626 double aR1Ext = theR1 + theW1;
1629 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1630 aP0->GetLastFunction()->SetDescription("");
1631 Handle(GEOM_Object) aVX = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
1632 Handle(GEOM_Object) aVY = myBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
1633 aVX->GetLastFunction()->SetDescription("");
1634 aVY->GetLastFunction()->SetDescription("");
1635 Handle(GEOM_Object) aPlane_OX = myBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
1636 Handle(GEOM_Object) aPlane_OY = myBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
1637 aPlane_OX->GetLastFunction()->SetDescription("");
1638 aPlane_OY->GetLastFunction()->SetDescription("");
1640 Handle(GEOM_Object) Te4 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
1642 SetErrorCode("Impossible to build mirror of quarter TShape");
1646 Handle(GEOM_Object) Te5 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
1648 SetErrorCode("Impossible to build mirror of half TShape");
1652 Handle(GEOM_Object) Te6 = myTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
1654 SetErrorCode("Impossible to build mirror of half TShape");
1658 std::list<Handle(GEOM_Object)> aShapesList;
1659 aShapesList.push_back(theShape);
1660 aShapesList.push_back(Te4);
1661 aShapesList.push_back(Te5);
1662 aShapesList.push_back(Te6);
1663 Handle(GEOM_Object) Te7 = myShapesOperations->MakeCompound(aShapesList);
1665 SetErrorCode("Impossible to build compound");
1669 // Copy source shape
1670 TopoDS_Shape aShapeCopy;
1671 TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
1672 TNaming_CopyShape::CopyTool(Te7->GetValue(), aMapTShapes, aShapeCopy);
1674 Handle(GEOM_Object) Te8 = myShapesOperations->MakeGlueFaces(Te7, 1e-7, true);
1676 SetErrorCode("Impossible to glue faces of TShape");
1680 TopoDS_Shape aShape = Te8->GetValue();
1681 BRepCheck_Analyzer anAna (aShape, Standard_True);
1683 if (!anAna.IsValid()) {
1684 // Try to do gluing with the tolerance equal to maximal
1685 // tolerance of vertices of the source shape.
1686 Standard_Real aTolMax = -RealLast();
1688 for (TopExp_Explorer ExV (aShapeCopy, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1689 TopoDS_Vertex aVertex = TopoDS::Vertex(ExV.Current());
1690 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
1692 if (aTol > aTolMax) {
1698 Te7->GetLastFunction()->SetValue(aShapeCopy);
1699 Te8 = myShapesOperations->MakeGlueFaces(Te7, aTolMax, true);
1702 SetErrorCode("Impossible to glue faces of TShape");
1706 aShape = Te8->GetValue();
1710 theShape->GetLastFunction()->SetValue(aShape);
1712 Te4->GetLastFunction()->SetDescription("");
1713 Te5->GetLastFunction()->SetDescription("");
1714 Te6->GetLastFunction()->SetDescription("");
1715 Te7->GetLastFunction()->SetDescription("");
1716 Te8->GetLastFunction()->SetDescription("");
1722 //=======================================================================
1723 //function : MakePipeTShapeThicknessReduction
1724 //purpose : Static method. Add thiskness reduction elements at the three
1725 // open ends of the T-Shape.
1726 //=======================================================================
1727 TopoDS_Shape AdvancedEngine_IOperations::MakePipeTShapeThicknessReduction
1728 (TopoDS_Shape theShape,
1729 double r1, double w1, double l1,
1730 double r2, double w2, double l2,
1731 double rL, double wL, double ltransL, double lthinL,
1732 double rR, double wR, double ltransR, double lthinR,
1733 double rI, double wI, double ltransI, double lthinI,
1734 bool fuseReductions)
1736 // Add thickness reduction elements
1737 // at the three extremities: Left, Right and Incident
1739 // ---------------------.
1741 // ---------------------. \
1742 // ^ \ '-----------------.
1744 // | '-----------------'
1746 // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--
1749 TopoDS_Shape aResult = theShape;
1750 double aTol = Precision::Confusion();
1752 gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
1754 // Left reduction (rL, wL, ltransL, lthinL)
1755 if (rL > aTol && wL > aTol && ltransL > aTol) {
1756 gp_Pnt aPLeft (-l1, 0, 0);
1757 gp_Ax2 anAxesLeft (aPLeft, -aVX, aVZ);
1758 TopoDS_Shape aReductionLeft = AdvancedEngine_IOperations::MakeThicknessReduction
1759 (anAxesLeft, r1, w1, rL, wL, ltransL, lthinL, fuseReductions);
1761 if (fuseReductions) {
1762 BRepAlgoAPI_Fuse fuseL (aResult, aReductionLeft);
1763 if (!fuseL.IsDone())
1764 StdFail_NotDone::Raise("Cannot fuse Te with left reduction");
1765 aResult = fuseL.Shape();
1772 B.Add(C, aReductionLeft);
1778 if (rR > aTol && wR > aTol && ltransR > aTol) {
1779 gp_Pnt aPRight (l1, 0, 0);
1780 gp_Ax2 anAxesRight (aPRight, aVX, aVZ);
1781 TopoDS_Shape aReductionRight = AdvancedEngine_IOperations::MakeThicknessReduction
1782 (anAxesRight, r1, w1, rR, wR, ltransR, lthinR, fuseReductions);
1784 if (fuseReductions) {
1785 BRepAlgoAPI_Fuse fuseR (aResult, aReductionRight);
1786 if (!fuseR.IsDone())
1787 StdFail_NotDone::Raise("Cannot fuse Te with right reduction");
1788 aResult = fuseR.Shape();
1795 B.Add(C, aReductionRight);
1800 // Incident reduction
1801 if (rI > aTol && wI > aTol && ltransI > aTol) {
1802 gp_Pnt aPInci (0, 0, l2);
1803 gp_Ax2 anAxesInci (aPInci, aVZ, aVX);
1804 TopoDS_Shape aReductionInci = AdvancedEngine_IOperations::MakeThicknessReduction
1805 (anAxesInci, r2, w2, rI, wI, ltransI, lthinI, fuseReductions);
1807 if (fuseReductions) {
1808 BRepAlgoAPI_Fuse fuseInci (aResult, aReductionInci);
1809 if (!fuseInci.IsDone())
1810 StdFail_NotDone::Raise("Cannot fuse Te with incident reduction");
1811 aResult = fuseInci.Shape();
1818 B.Add(C, aReductionInci);
1823 // Get rid of extra compounds
1824 TopTools_ListOfShape listShapeRes;
1825 GEOMUtils::AddSimpleShapes(aResult, listShapeRes);
1826 aResult = listShapeRes.First(); // useful for the case "fuseReductions == true"
1828 if (!fuseReductions && listShapeRes.Extent() > 1) {
1829 // Simplify T-Shape compound (get rid of sub-compounds) and glue duplicated faces
1834 TopTools_ListIteratorOfListOfShape itSub (listShapeRes);
1835 for (; itSub.More(); itSub.Next())
1836 B.Add(C, itSub.Value());
1839 aResult = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
1845 //=======================================================================
1846 //function : MakeThicknessReduction
1847 //purpose : Static method. Create one thickness reduction element.
1848 //=======================================================================
1849 TopoDS_Shape AdvancedEngine_IOperations::MakeThicknessReduction (gp_Ax2 theAxes,
1850 const double R, const double W,
1851 const double Rthin, const double Wthin,
1852 const double Ltrans, const double Lthin,
1855 double aTol = Precision::Confusion();
1856 if (Rthin < aTol || Wthin < aTol || Ltrans < aTol) {
1857 StdFail_NotDone::Raise("Cannot build thickness reduction: too small values");
1859 bool isThinPart = (Lthin > aTol);
1864 // ^ \ '-----------------.
1866 // | '-----------------'
1868 // --.--.--.--.--.--.--.--.--.--.--.--.--> theAxes.Direction()
1871 double RExt = R + W;
1872 double RthinExt = Rthin + Wthin;
1874 gp_Dir aNormal = theAxes.Direction();
1875 gp_Dir anXDir = theAxes.XDirection();
1876 gp_Pnt aPntCyl (theAxes.Location().XYZ() + aNormal.XYZ()*Ltrans);
1877 gp_Ax2 anAxesCyl (aPntCyl, aNormal, anXDir);
1879 // Build the transition part
1880 BRepPrimAPI_MakeCone ConeExt (theAxes, RExt, RthinExt, Ltrans);
1881 BRepPrimAPI_MakeCone ConeInt (theAxes, R, Rthin, Ltrans);
1884 if (!ConeExt.IsDone() || !ConeInt.IsDone())
1885 StdFail_NotDone::Raise("Cannot build cones of thickness reduction");
1886 BRepAlgoAPI_Cut cut1 (ConeExt.Shape(), ConeInt.Shape());
1888 StdFail_NotDone::Raise("Coudn't build transition part of thickness reduction");
1889 TopoDS_Shape aReduction = cut1.Shape();
1891 // Build the thin part, if required
1892 TopoDS_Shape aThinPart;
1894 BRepPrimAPI_MakeCylinder CExt (anAxesCyl, RthinExt, Lthin);
1895 BRepPrimAPI_MakeCylinder CInt (anAxesCyl, Rthin, Lthin);
1898 if (!CExt.IsDone() || !CInt.IsDone())
1899 StdFail_NotDone::Raise("Cannot build cylinders of thickness reduction");
1900 BRepAlgoAPI_Cut cut2 (CExt.Shape(), CInt.Shape());
1902 StdFail_NotDone::Raise("Coudn't build thin part of thickness reduction");
1903 aThinPart = cut2.Shape();
1909 BRepAlgoAPI_Fuse fuse1 (aReduction, aThinPart);
1910 if (!fuse1.IsDone())
1911 StdFail_NotDone::Raise("Cannot fuse parts of thickness reduction");
1912 aReduction = fuse1.Shape();
1916 // Partition the reduction on blocks
1917 gp_Ax3 anAxesPln1 (aPntCyl, theAxes.XDirection(), aNormal);
1918 gp_Ax3 anAxesPln2 (aPntCyl, theAxes.YDirection(), aNormal);
1919 gp_Pln aPln1 (anAxesPln1);
1920 gp_Pln aPln2 (anAxesPln2);
1921 double aSize = Ltrans + Lthin + R + Rthin + Wthin; // to guarantee enough size in all directions
1922 TopoDS_Shape aTool1 = BRepBuilderAPI_MakeFace(aPln1, -aSize, +aSize, -aSize, +aSize).Shape();
1923 TopoDS_Shape aTool2 = BRepBuilderAPI_MakeFace(aPln2, -aSize, +aSize, -aSize, +aSize).Shape();
1925 GEOMAlgo_Splitter PS;
1926 PS.AddArgument(aReduction);
1928 PS.AddArgument(aThinPart);
1931 PS.SetLimit(TopAbs_SOLID);
1934 aReduction = PS.Shape();
1940 //=============================================================================
1943 * \brief Create a T-shape object with specified caracteristics for the main and
1944 * the incident pipes (radius, width, half-length).
1945 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1946 * \param theR1 Internal radius of main pipe
1947 * \param theW1 Width of main pipe
1948 * \param theL1 Half-length of main pipe
1949 * \param theR2 Internal radius of incident pipe (R2 < R1)
1950 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1951 * \param theL2 Half-length of incident pipe
1952 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1953 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1955 //=============================================================================
1956 Handle(TColStd_HSequenceOfTransient)
1957 AdvancedEngine_IOperations::MakePipeTShape(double theR1, double theW1, double theL1,
1958 double theR2, double theW2, double theL2,
1959 double theRL, double theWL, double theLtransL, double theLthinL,
1960 double theRR, double theWR, double theLtransR, double theLthinR,
1961 double theRI, double theWI, double theLtransI, double theLthinI,
1964 MESSAGE("AdvancedEngine_IOperations::MakePipeTShape");
1967 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1969 //Add a new shape function with parameters
1970 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1971 if (aFunction.IsNull()) return NULL;
1973 //Check if the function is set correctly
1974 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
1976 AdvancedEngine_IPipeTShape aData (aFunction);
1984 aData.SetHexMesh(theHexMesh);
1986 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
1987 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
1988 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
1990 //Compute the resulting value
1992 #if OCC_VERSION_LARGE > 0x06010000
1995 if (!GetSolver()->ComputeFunction(aFunction)) {
1996 SetErrorCode("TShape driver failed");
2001 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2003 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2007 if (isTRL || isTRR || isTRI) {
2008 // Add thickness reduction elements
2009 // at the three extremities: Left, Right and Incident
2010 TopoDS_Shape aResShape =
2011 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2012 theRL, theWL, theLtransL, theLthinL,
2013 theRR, theWR, theLtransR, theLthinR,
2014 theRI, theWI, theLtransI, theLthinI,
2016 aFunction->SetValue(aResShape);
2019 catch (Standard_Failure) {
2020 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2021 SetErrorCode(aFail->GetMessageString());
2025 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2026 aSeq->Append(aShape);
2031 if (!MakeGroups(aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2032 0., 0., 0., aSeq, gp_Trsf()))
2036 // Get internal group.
2037 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2038 theRR, theLtransR, theRI, theLtransI,
2043 catch (Standard_Failure) {
2044 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2045 SetErrorCode(aFail->GetMessageString());
2049 //Make a Python command
2050 TCollection_AsciiString anEntry, aListRes("[");
2051 // Iterate over the sequence aSeq
2052 Standard_Integer aNbGroups = aSeq->Length();
2053 Standard_Integer i = 1;
2054 for (; i <= aNbGroups; i++) {
2055 Handle(Standard_Transient) anItem = aSeq->Value(i);
2056 if (anItem.IsNull()) continue;
2057 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2058 if (aGroup.IsNull()) continue;
2059 //Make a Python command
2060 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2061 aListRes += anEntry + ", ";
2063 aListRes.Trunc(aListRes.Length() - 2);
2065 GEOM::TPythonDump pd (aFunction);
2067 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2068 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2069 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2072 // thickness reduction
2074 pd << ", theRL=" << theRL << ", theWL=" << theWL
2075 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2077 pd << ", theRR=" << theRR << ", theWR=" << theWR
2078 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2080 pd << ", theRI=" << theRI << ", theWI=" << theWI
2081 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2090 //=============================================================================
2092 * MakePipeTShapeWithPosition
2093 * Create a T-shape object with specified caracteristics for the main and
2094 * the incident pipes (radius, width, half-length).
2095 * The extremities of the main pipe are located on junctions points P1 and P2.
2096 * The extremity of the incident pipe is located on junction point P3.
2097 * \param theR1 Internal radius of main pipe
2098 * \param theW1 Width of main pipe
2099 * \param theL1 Half-length of main pipe
2100 * \param theR2 Internal radius of incident pipe (R2 < R1)
2101 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2102 * \param theL2 Half-length of incident pipe
2103 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2104 * \param theP1 1st junction point of main pipe
2105 * \param theP2 2nd junction point of main pipe
2106 * \param theP3 Junction point of incident pipe
2107 * \return List of GEOM_Objects, containing the created shape and propagation groups..
2109 //=============================================================================
2110 Handle(TColStd_HSequenceOfTransient)
2111 AdvancedEngine_IOperations::MakePipeTShapeWithPosition
2112 (double theR1, double theW1, double theL1,
2113 double theR2, double theW2, double theL2,
2114 double theRL, double theWL, double theLtransL, double theLthinL,
2115 double theRR, double theWR, double theLtransR, double theLthinR,
2116 double theRI, double theWI, double theLtransI, double theLthinI,
2118 Handle(GEOM_Object) theP1,
2119 Handle(GEOM_Object) theP2,
2120 Handle(GEOM_Object) theP3)
2124 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2128 //Add a new shape function with parameters
2129 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
2130 if (aFunction.IsNull()) return NULL;
2132 //Check if the function is set correctly
2133 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2135 // Check new position
2136 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2140 AdvancedEngine_IPipeTShape aData(aFunction);
2148 aData.SetHexMesh(theHexMesh);
2150 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2151 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2152 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2154 //Compute the resulting value
2156 #if OCC_VERSION_LARGE > 0x06010000
2159 if (!GetSolver()->ComputeFunction(aFunction)) {
2160 SetErrorCode("TShape driver failed");
2165 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2167 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2171 if (isTRL || isTRR || isTRI) {
2172 // Add thickness reduction elements
2173 // at the three extremities: Left, Right and Incident
2174 TopoDS_Shape aResShape =
2175 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2176 theRL, theWL, theLtransL, theLthinL,
2177 theRR, theWR, theLtransR, theLthinR,
2178 theRI, theWI, theLtransI, theLthinI,
2180 aFunction->SetValue(aResShape);
2183 catch (Standard_Failure) {
2184 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2185 SetErrorCode(aFail->GetMessageString());
2189 TopoDS_Shape Te = aShape->GetValue();
2192 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2193 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
2194 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2195 aFunction->SetValue(aTrsf_Shape);
2197 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2198 aSeq->Append(aShape);
2203 if (!MakeGroups(aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2204 0., 0., 0., aSeq, aTrsf)) {
2209 // Get internal group.
2210 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2211 theRR, theLtransR, theRI, theLtransI,
2216 catch (Standard_Failure) {
2217 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2218 SetErrorCode(aFail->GetMessageString());
2222 //Make a Python command
2223 TCollection_AsciiString anEntry, aListRes("[");
2224 // Iterate over the sequence aSeq
2225 Standard_Integer aNbGroups = aSeq->Length();
2226 Standard_Integer i = 1;
2227 for (; i <= aNbGroups; i++) {
2228 Handle(Standard_Transient) anItem = aSeq->Value(i);
2229 if (anItem.IsNull()) continue;
2230 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2231 if (aGroup.IsNull()) continue;
2232 //Make a Python command
2233 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2234 aListRes += anEntry + ", ";
2236 aListRes.Trunc(aListRes.Length() - 2);
2238 GEOM::TPythonDump pd (aFunction);
2240 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2241 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2242 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2243 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3;
2245 // thickness reduction
2247 pd << ", theRL=" << theRL << ", theWL=" << theWL
2248 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2250 pd << ", theRR=" << theRR << ", theWR=" << theWR
2251 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2253 pd << ", theRI=" << theRI << ", theWI=" << theWI
2254 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2263 //=============================================================================
2265 * MakePipeTShapeChamfer
2266 * Create a T-shape object with specified caracteristics for the main and
2267 * the incident pipes (radius, width, half-length). A chamfer is created
2268 * on the junction of the pipes.
2269 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2270 * \param theR1 Internal radius of main pipe
2271 * \param theW1 Width of main pipe
2272 * \param theL1 Half-length of main pipe
2273 * \param theR2 Internal radius of incident pipe (R2 < R1)
2274 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2275 * \param theL2 Half-length of incident pipe
2276 * \param theH Height of chamfer.
2277 * \param theW Width of chamfer.
2278 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2279 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2281 //=============================================================================
2282 Handle(TColStd_HSequenceOfTransient)
2283 AdvancedEngine_IOperations::MakePipeTShapeChamfer
2284 (double theR1, double theW1, double theL1,
2285 double theR2, double theW2, double theL2,
2286 double theRL, double theWL, double theLtransL, double theLthinL,
2287 double theRR, double theWR, double theLtransR, double theLthinR,
2288 double theRI, double theWI, double theLtransI, double theLthinI,
2289 double theH, double theW,
2294 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2295 //Add a new shape function with parameters
2296 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2297 if (aFunction.IsNull()) return NULL;
2299 //Check if the function is set correctly
2300 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2302 AdvancedEngine_IPipeTShape aData(aFunction);
2312 aData.SetHexMesh(theHexMesh);
2314 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2315 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2316 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2318 //Compute the resulting value
2320 #if OCC_VERSION_LARGE > 0x06010000
2323 if (!GetSolver()->ComputeFunction(aFunction)) {
2324 SetErrorCode("TShape driver failed");
2328 catch (Standard_Failure) {
2329 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2330 SetErrorCode(aFail->GetMessageString());
2335 TopoDS_Shape aShapeShape = aShape->GetValue();
2336 TopTools_IndexedMapOfShape anEdgesIndices;
2337 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2338 // Common edges on external cylinders
2339 Handle(GEOM_Object) box_e;
2341 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2344 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2346 box_e->GetLastFunction()->SetDescription("");
2347 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2348 box_e->GetLastFunction()->SetDescription("");
2350 Handle(TColStd_HSequenceOfInteger) edges_e =
2351 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2352 box_e->GetLastFunction()->SetDescription("");
2354 if (edges_e.IsNull() || edges_e->Length() == 0) {
2355 SetErrorCode("External edges not found");
2358 int nbEdgesInChamfer = 0;
2359 std::list<int> theEdges;
2360 for (int i=1; i<=edges_e->Length();i++) {
2361 int edgeID = edges_e->Value(i);
2362 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2363 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2367 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2368 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2369 nbEdgesInChamfer ++;
2370 theEdges.push_back(edgeID);
2374 if (theHexMesh && nbEdgesInChamfer == 1)
2377 Handle(GEOM_Object) aChamfer;
2379 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2381 catch (Standard_Failure) {
2382 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2383 SetErrorCode(aFail->GetMessageString());
2386 if (aChamfer.IsNull()) {
2387 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2390 aChamfer->GetLastFunction()->SetDescription("");
2392 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2393 aFunction->SetValue(aChamferShape);
2397 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2399 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2403 // Add thickness reduction elements
2404 // at the three extremities: Left, Right and Incident
2406 #if OCC_VERSION_LARGE > 0x06010000
2409 if (isTRL || isTRR || isTRI) {
2410 TopoDS_Shape aResShape =
2411 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2412 theRL, theWL, theLtransL, theLthinL,
2413 theRR, theWR, theLtransR, theLthinR,
2414 theRI, theWI, theLtransI, theLthinI,
2416 aFunction->SetValue(aResShape);
2419 catch (Standard_Failure) {
2420 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2421 SetErrorCode(aFail->GetMessageString());
2425 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2426 aSeq->Append(aShape);
2431 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2432 theH, theW, 0., aSeq, gp_Trsf()))
2436 // Get internal group.
2437 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2438 theRR, theLtransR, theRI, theLtransI,
2443 catch (Standard_Failure) {
2444 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2445 SetErrorCode(aFail->GetMessageString());
2449 //Make a Python command
2450 TCollection_AsciiString anEntry, aListRes("[");
2451 // Iterate over the sequence aSeq
2452 Standard_Integer aNbGroups = aSeq->Length();
2453 Standard_Integer i = 1;
2454 for (; i <= aNbGroups; i++) {
2455 Handle(Standard_Transient) anItem = aSeq->Value(i);
2456 if (anItem.IsNull()) continue;
2457 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2458 if (aGroup.IsNull()) continue;
2459 //Make a Python command
2460 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2461 aListRes += anEntry + ", ";
2463 aListRes.Trunc(aListRes.Length() - 2);
2465 GEOM::TPythonDump pd (aFunction);
2467 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2468 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2469 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2470 << theH << ", " << theW << ", " << theHexMesh;
2472 // thickness reduction
2474 pd << ", theRL=" << theRL << ", theWL=" << theWL
2475 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2477 pd << ", theRR=" << theRR << ", theWR=" << theWR
2478 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2480 pd << ", theRI=" << theRI << ", theWI=" << theWI
2481 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2490 //=============================================================================
2492 * MakePipeTShapeChamferWithPosition
2493 * Create a T-shape object with specified caracteristics for the main and
2494 * the incident pipes (radius, width, half-length). A chamfer is created
2495 * on the junction of the pipes.
2496 * The extremities of the main pipe are located on junctions points P1 and P2.
2497 * The extremity of the incident pipe is located on junction point P3.
2498 * \param theR1 Internal radius of main pipe
2499 * \param theW1 Width of main pipe
2500 * \param theL1 Half-length of main pipe
2501 * \param theR2 Internal radius of incident pipe (R2 < R1)
2502 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2503 * \param theL2 Half-length of incident pipe
2504 * \param theH Height of chamfer.
2505 * \param theW Width of chamfer.
2506 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2507 * \param theP1 1st junction point of main pipe
2508 * \param theP2 2nd junction point of main pipe
2509 * \param theP3 Junction point of incident pipe
2510 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2512 //=============================================================================
2513 Handle(TColStd_HSequenceOfTransient)
2514 AdvancedEngine_IOperations::MakePipeTShapeChamferWithPosition
2515 (double theR1, double theW1, double theL1,
2516 double theR2, double theW2, double theL2,
2517 double theRL, double theWL, double theLtransL, double theLthinL,
2518 double theRR, double theWR, double theLtransR, double theLthinR,
2519 double theRI, double theWI, double theLtransI, double theLthinI,
2520 double theH, double theW,
2522 Handle(GEOM_Object) theP1,
2523 Handle(GEOM_Object) theP2,
2524 Handle(GEOM_Object) theP3)
2528 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2529 //Add a new shape function with parameters
2530 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2531 if (aFunction.IsNull()) return NULL;
2533 //Check if the function is set correctly
2534 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2536 // Check new position
2537 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2541 AdvancedEngine_IPipeTShape aData(aFunction);
2551 aData.SetHexMesh(theHexMesh);
2553 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2554 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2555 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2557 //Compute the resulting value
2559 #if OCC_VERSION_LARGE > 0x06010000
2562 if (!GetSolver()->ComputeFunction(aFunction)) {
2563 SetErrorCode("TShape driver failed");
2567 catch (Standard_Failure) {
2568 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2569 SetErrorCode(aFail->GetMessageString());
2574 TopoDS_Shape aShapeShape = aShape->GetValue();
2575 TopTools_IndexedMapOfShape anEdgesIndices;
2576 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2577 // Common edges on external cylinders
2578 Handle(GEOM_Object) box_e;
2580 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2583 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2585 box_e->GetLastFunction()->SetDescription("");
2586 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2587 box_e->GetLastFunction()->SetDescription("");
2589 Handle(TColStd_HSequenceOfInteger) edges_e =
2590 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2591 box_e->GetLastFunction()->SetDescription("");
2593 if (edges_e.IsNull() || edges_e->Length() == 0) {
2594 SetErrorCode("External edges not found");
2597 int nbEdgesInChamfer = 0;
2598 std::list<int> theEdges;
2599 for (int i=1; i<=edges_e->Length();i++) {
2600 int edgeID = edges_e->Value(i);
2601 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2602 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2604 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2605 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2606 nbEdgesInChamfer ++;
2607 theEdges.push_back(edgeID);
2611 if (theHexMesh && nbEdgesInChamfer == 1)
2614 Handle(GEOM_Object) aChamfer;
2616 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2618 catch (Standard_Failure) {
2619 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2620 SetErrorCode(aFail->GetMessageString());
2623 if (aChamfer.IsNull()) {
2624 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2627 aChamfer->GetLastFunction()->SetDescription("");
2629 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2630 aFunction->SetValue(aChamferShape);
2634 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2636 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2640 // Add thickness reduction elements
2641 // at the three extremities: Left, Right and Incident
2643 #if OCC_VERSION_LARGE > 0x06010000
2646 if (isTRL || isTRR || isTRI) {
2647 TopoDS_Shape aResShape =
2648 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2649 theRL, theWL, theLtransL, theLthinL,
2650 theRR, theWR, theLtransR, theLthinR,
2651 theRI, theWI, theLtransI, theLthinI,
2653 aFunction->SetValue(aResShape);
2656 catch (Standard_Failure) {
2657 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2658 SetErrorCode(aFail->GetMessageString());
2663 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2664 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
2665 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2666 aFunction->SetValue(aTrsf_Shape);
2668 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2669 aSeq->Append(aShape);
2674 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2675 theH, theW, 0., aSeq, aTrsf))
2679 // Get internal group.
2680 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2681 theRR, theLtransR, theRI, theLtransI,
2686 catch (Standard_Failure) {
2687 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2688 SetErrorCode(aFail->GetMessageString());
2692 //Make a Python command
2693 TCollection_AsciiString anEntry, aListRes("[");
2694 // Iterate over the sequence aSeq
2695 Standard_Integer aNbGroups = aSeq->Length();
2696 Standard_Integer i = 1;
2697 for (; i <= aNbGroups; i++) {
2698 Handle(Standard_Transient) anItem = aSeq->Value(i);
2699 if (anItem.IsNull()) continue;
2700 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2701 if (aGroup.IsNull()) continue;
2702 //Make a Python command
2703 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2704 aListRes += anEntry + ", ";
2706 aListRes.Trunc(aListRes.Length() - 2);
2708 GEOM::TPythonDump pd (aFunction);
2710 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2711 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2712 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2713 << theH << ", " << theW << ", " << theHexMesh << ", "
2714 << theP1 << ", " << theP2 << ", " << theP3;
2716 // thickness reduction
2718 pd << ", theRL=" << theRL << ", theWL=" << theWL
2719 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2721 pd << ", theRR=" << theRR << ", theWR=" << theWR
2722 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2724 pd << ", theRI=" << theRI << ", theWI=" << theWI
2725 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2734 //=============================================================================
2736 * MakePipeTShapeFillet
2737 * Create a T-shape object with specified caracteristics for the main and
2738 * the incident pipes (radius, width, half-length). A fillet is created
2739 * on the junction of the pipes.
2740 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2741 * \param theR1 Internal radius of main pipe
2742 * \param theW1 Width of main pipe
2743 * \param theL1 Half-length of main pipe
2744 * \param theR2 Internal radius of incident pipe (R2 < R1)
2745 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2746 * \param theL2 Half-length of incident pipe
2747 * \param theRF Radius of curvature of fillet.
2748 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2749 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2751 //=============================================================================
2752 Handle(TColStd_HSequenceOfTransient)
2753 AdvancedEngine_IOperations::MakePipeTShapeFillet
2754 (double theR1, double theW1, double theL1,
2755 double theR2, double theW2, double theL2,
2756 double theRL, double theWL, double theLtransL, double theLthinL,
2757 double theRR, double theWR, double theLtransR, double theLthinR,
2758 double theRI, double theWI, double theLtransI, double theLthinI,
2759 double theRF, bool theHexMesh)
2763 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2764 //Add a new shape function with parameters
2765 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2766 if (aFunction.IsNull()) return NULL;
2768 //Check if the function is set correctly
2769 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2771 AdvancedEngine_IPipeTShape aData(aFunction);
2780 aData.SetHexMesh(theHexMesh);
2782 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2783 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2784 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2786 //Compute the resulting value
2788 #if OCC_VERSION_LARGE > 0x06010000
2791 if (!GetSolver()->ComputeFunction(aFunction)) {
2792 SetErrorCode("TShape driver failed");
2796 catch (Standard_Failure) {
2797 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2798 SetErrorCode(aFail->GetMessageString());
2803 TopoDS_Shape aShapeShape = aShape->GetValue();
2804 TopTools_IndexedMapOfShape anEdgesIndices;
2805 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2806 // Common edges on external cylinders
2807 Handle(GEOM_Object) box_e;
2809 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2812 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2814 box_e->GetLastFunction()->SetDescription("");
2815 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2816 box_e->GetLastFunction()->SetDescription("");
2818 Handle(TColStd_HSequenceOfInteger) edges_e =
2819 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2820 box_e->GetLastFunction()->SetDescription("");
2822 if (edges_e.IsNull() || edges_e->Length() == 0) {
2823 SetErrorCode("External edges not found");
2826 int nbEdgesInFillet = 0;
2827 std::list<int> theEdges;
2828 for (int i=1; i<=edges_e->Length();i++) {
2829 int edgeID = edges_e->Value(i);
2830 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2831 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2833 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2834 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2836 theEdges.push_back(edgeID);
2840 if (theHexMesh && nbEdgesInFillet == 1)
2844 Handle(GEOM_Object) aFillet;
2846 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2848 catch (Standard_Failure) {
2849 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2850 SetErrorCode(aFail->GetMessageString());
2853 if (aFillet.IsNull()) {
2854 //SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
2855 SetErrorCode(myLocalOperations->GetErrorCode());
2858 aFillet->GetLastFunction()->SetDescription("");
2860 TopoDS_Shape aFilletShape = aFillet->GetValue();
2861 aFunction->SetValue(aFilletShape);
2864 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (1)
2865 // the following block, when enabled, leads to partitioning problems
2867 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (1)
2868 // BEGIN: Limit tolerances (debug)
2869 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
2870 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
2871 aShape->GetLastFunction()->SetValue(aCorr1Shape);
2872 aCorr1->GetLastFunction()->SetDescription("");
2873 // END: Limit tolerances (debug)
2874 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (2)
2876 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (2)
2879 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2881 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2885 // Add thickness reduction elements
2886 // at the three extremities: Left, Right and Incident
2888 #if OCC_VERSION_LARGE > 0x06010000
2891 if (isTRL || isTRR || isTRI) {
2892 TopoDS_Shape aResShape =
2893 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2894 theRL, theWL, theLtransL, theLthinL,
2895 theRR, theWR, theLtransR, theLthinR,
2896 theRI, theWI, theLtransI, theLthinI,
2898 aFunction->SetValue(aResShape);
2901 catch (Standard_Failure) {
2902 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2903 SetErrorCode(aFail->GetMessageString());
2907 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2908 aSeq->Append(aShape);
2913 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
2914 0., 0., theRF, aSeq, gp_Trsf()))
2918 // Get internal group.
2919 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2920 theRR, theLtransR, theRI, theLtransI,
2925 catch (Standard_Failure) {
2926 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2927 SetErrorCode(aFail->GetMessageString());
2931 //Make a Python command
2932 TCollection_AsciiString anEntry, aListRes("[");
2933 // Iterate over the sequence aSeq
2934 Standard_Integer aNbGroups = aSeq->Length();
2935 Standard_Integer i = 1;
2936 for (; i <= aNbGroups; i++) {
2937 Handle(Standard_Transient) anItem = aSeq->Value(i);
2938 if (anItem.IsNull()) continue;
2939 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2940 if (aGroup.IsNull()) continue;
2941 //Make a Python command
2942 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2943 aListRes += anEntry + ", ";
2945 aListRes.Trunc(aListRes.Length() - 2);
2947 GEOM::TPythonDump pd (aFunction);
2949 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
2950 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2951 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2952 << theRF << ", " << theHexMesh;
2954 // thickness reduction
2956 pd << ", theRL=" << theRL << ", theWL=" << theWL
2957 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2959 pd << ", theRR=" << theRR << ", theWR=" << theWR
2960 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2962 pd << ", theRI=" << theRI << ", theWI=" << theWI
2963 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2972 //=============================================================================
2974 * MakePipeTShapeFilletWithPosition
2975 * \brief Create a T-shape object with specified caracteristics for the main and
2976 * the incident pipes (radius, width, half-length). A fillet is created
2977 * on the junction of the pipes.
2978 * The extremities of the main pipe are located on junctions points P1 and P2.
2979 * The extremity of the incident pipe is located on junction point P3.
2980 * \param theR1 Internal radius of main pipe
2981 * \param theW1 Width of main pipe
2982 * \param theL1 Half-length of main pipe
2983 * \param theR2 Internal radius of incident pipe (R2 < R1)
2984 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2985 * \param theL2 Half-length of incident pipe
2986 * \param theRF Radius of curvature of fillet
2987 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2988 * \param theP1 1st junction point of main pipe
2989 * \param theP2 2nd junction point of main pipe
2990 * \param theP3 Junction point of incident pipe
2991 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2993 //=============================================================================
2994 Handle(TColStd_HSequenceOfTransient)
2995 AdvancedEngine_IOperations::MakePipeTShapeFilletWithPosition
2996 (double theR1, double theW1, double theL1,
2997 double theR2, double theW2, double theL2,
2998 double theRL, double theWL, double theLtransL, double theLthinL,
2999 double theRR, double theWR, double theLtransR, double theLthinR,
3000 double theRI, double theWI, double theLtransI, double theLthinI,
3001 double theRF, bool theHexMesh,
3002 Handle(GEOM_Object) theP1,
3003 Handle(GEOM_Object) theP2,
3004 Handle(GEOM_Object) theP3)
3008 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
3009 //Add a new shape function with parameters
3010 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
3011 if (aFunction.IsNull()) return NULL;
3013 //Check if the function is set correctly
3014 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
3016 // Check new position
3017 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
3021 AdvancedEngine_IPipeTShape aData(aFunction);
3030 aData.SetHexMesh(theHexMesh);
3032 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
3033 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
3034 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
3036 //Compute the resulting value
3038 #if OCC_VERSION_LARGE > 0x06010000
3041 if (!GetSolver()->ComputeFunction(aFunction)) {
3042 SetErrorCode("TShape driver failed");
3046 catch (Standard_Failure) {
3047 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3048 SetErrorCode(aFail->GetMessageString());
3053 TopoDS_Shape aShapeShape = aShape->GetValue();
3054 TopTools_IndexedMapOfShape anEdgesIndices;
3055 TopExp::MapShapes(aShapeShape, anEdgesIndices);
3056 // Common edges on external cylinders
3057 Handle(GEOM_Object) box_e;
3059 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
3062 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
3064 box_e->GetLastFunction()->SetDescription("");
3065 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
3066 box_e->GetLastFunction()->SetDescription("");
3068 Handle(TColStd_HSequenceOfInteger) edges_e =
3069 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
3070 box_e->GetLastFunction()->SetDescription("");
3072 if (edges_e.IsNull() || edges_e->Length() == 0) {
3073 SetErrorCode("External edges not found");
3076 int nbEdgesInFillet = 0;
3077 std::list<int> theEdges;
3078 for (int i=1; i<=edges_e->Length();i++) {
3079 int edgeID = edges_e->Value(i);
3080 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
3081 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
3083 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
3084 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
3086 theEdges.push_back(edgeID);
3090 if (theHexMesh && nbEdgesInFillet == 1)
3094 Handle(GEOM_Object) aFillet;
3096 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
3098 catch (Standard_Failure) {
3099 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3100 SetErrorCode(aFail->GetMessageString());
3103 if (aFillet.IsNull()) {
3104 SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
3107 aFillet->GetLastFunction()->SetDescription("");
3109 TopoDS_Shape aFilletShape = aFillet->GetValue();
3110 aFunction->SetValue(aFilletShape);
3113 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (3)
3114 // the following block, when enabled, leads to partitioning problems
3116 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (3)
3117 // BEGIN: Limit tolerances (debug)
3118 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
3119 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
3120 aShape->GetLastFunction()->SetValue(aCorr1Shape);
3121 aCorr1->GetLastFunction()->SetDescription("");
3122 // END: Limit tolerances (debug)
3123 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (4)
3125 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (4)
3128 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
3130 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
3134 // Add thickness reduction elements
3135 // at the three extremities: Left, Right and Incident
3137 #if OCC_VERSION_LARGE > 0x06010000
3140 if (isTRL || isTRR || isTRI) {
3141 TopoDS_Shape aResShape =
3142 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
3143 theRL, theWL, theLtransL, theLthinL,
3144 theRR, theWR, theLtransR, theLthinR,
3145 theRI, theWI, theLtransI, theLthinI,
3147 aFunction->SetValue(aResShape);
3150 catch (Standard_Failure) {
3151 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3152 SetErrorCode(aFail->GetMessageString());
3157 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
3158 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
3159 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
3160 aFunction->SetValue(aTrsf_Shape);
3162 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
3163 aSeq->Append(aShape);
3168 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
3169 0., 0., theRF, aSeq, aTrsf))
3173 // Get internal group.
3174 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
3175 theRR, theLtransR, theRI, theLtransI,
3180 catch (Standard_Failure) {
3181 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3182 SetErrorCode(aFail->GetMessageString());
3186 //Make a Python command
3187 TCollection_AsciiString anEntry, aListRes("[");
3188 // Iterate over the sequence aSeq
3189 Standard_Integer aNbGroups = aSeq->Length();
3190 Standard_Integer i = 1;
3191 for (; i <= aNbGroups; i++) {
3192 Handle(Standard_Transient) anItem = aSeq->Value(i);
3193 if (anItem.IsNull()) continue;
3194 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
3195 if (aGroup.IsNull()) continue;
3196 //Make a Python command
3197 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
3198 aListRes += anEntry + ", ";
3200 aListRes.Trunc(aListRes.Length() - 2);
3202 GEOM::TPythonDump pd (aFunction);
3204 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
3205 << theR1 << ", " << theW1 << ", " << theL1 << ", "
3206 << theR2 << ", " << theW2 << ", " << theL2 << ", "
3207 << theRF << ", " << theHexMesh << ", "
3208 << theP1 << ", " << theP2 << ", " << theP3;
3210 // thickness reduction
3212 pd << ", theRL=" << theRL << ", theWL=" << theWL
3213 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
3215 pd << ", theRR=" << theRR << ", theWR=" << theWR
3216 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
3218 pd << ", theRI=" << theRI << ", theWI=" << theWI
3219 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
3228 //=============================================================================
3230 * This function allows to create a disk already divided into blocks. It can be
3231 * used to create divided pipes for later meshing in hexaedra.
3232 * \param theR Radius of the disk
3233 * \param theRatio Relative size of the central square diagonal against the disk diameter
3234 * \param theOrientation Plane on which the disk will be built
3235 * \param thePattern The division pattern of the disk (hexagon or square in the center)
3236 * \return New GEOM_Object, containing the created shape.
3238 //=============================================================================
3239 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDisk (double theR, double theRatio,
3240 int theOrientation, int thePattern)
3244 if (theOrientation != 1 &&
3245 theOrientation != 2 &&
3246 theOrientation != 3)
3248 SetErrorCode("theOrientation must be 1(=OXY), 2(=OYZ) or 3(=OZX)");
3252 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3254 //Add a new shape function with parameters
3255 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_RATIO);
3256 if (aFunction.IsNull()) return NULL;
3258 //Check if the function is set correctly
3259 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3261 AdvancedEngine_IDividedDisk aData (aFunction);
3264 aData.SetRatio(theRatio);
3265 aData.SetOrientation(theOrientation);
3266 aData.SetType(thePattern);
3268 //Compute the resulting value
3270 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
3273 if (!GetSolver()->ComputeFunction(aFunction)) {
3274 SetErrorCode("DividedDisk driver failed");
3278 catch (Standard_Failure) {
3279 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3280 SetErrorCode(aFail->GetMessageString());
3284 std::string aPatternStr;
3289 aPatternStr = "GEOM.SQUARE";
3292 aPatternStr = "GEOM.HEXAGON";
3296 //Make a Python command
3297 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDisk(" << theR << ", " << theOrientation << ", " << aPatternStr.c_str() << ")";
3304 //=============================================================================
3306 * This function allows to create a disk already divided into blocks. It can be
3307 * used to create divided pipes for later meshing in hexaedra.
3308 * \param theR Radius of the disk
3309 * \param theRatio Relative size of the central square diagonal against the disk diameter
3310 * \return New GEOM_Object, containing the created shape.
3312 //=============================================================================
3313 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDiskPntVecR (Handle(GEOM_Object) thePnt,
3314 Handle(GEOM_Object) theVec,
3322 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3324 //Add a new shape function with parameters
3325 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_VECTOR_PNT);
3326 if (aFunction.IsNull()) return NULL;
3328 //Check if the function is set correctly
3329 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3331 AdvancedEngine_IDividedDisk aData (aFunction);
3333 Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
3334 Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
3336 if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
3338 aData.SetCenter(aRefPnt);
3339 aData.SetVector(aRefVec);
3342 aData.SetRatio(theRatio);
3343 aData.SetType(thePattern);
3345 //Compute the resulting value
3347 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
3350 if (!GetSolver()->ComputeFunction(aFunction)) {
3351 SetErrorCode("DividedDisk driver failed");
3355 catch (Standard_Failure) {
3356 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3357 SetErrorCode(aFail->GetMessageString());
3361 std::string aPatternStr;
3366 aPatternStr = "GEOM.SQUARE";
3369 aPatternStr = "GEOM.HEXAGON";
3374 //Make a Python command
3375 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDiskPntVecR(" << thePnt << ", " << theVec << ", " << theR << ", " << aPatternStr.c_str() << ")";
3382 //=============================================================================
3384 * Builds a cylinder prepared for hexa meshes
3385 * \param theR Radius of the cylinder
3386 * \param theH Height of the cylinder
3387 * \return New GEOM_Object, containing the created shape.
3389 //=============================================================================
3390 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedCylinder (double theR,
3397 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDCYLINDER);
3399 Handle(GEOM_Object) aBaseShape = MakeDividedDisk(theR, 67.0, 1, thePattern);
3400 aBaseShape->GetLastFunction()->SetDescription(""); // Erase dump of MakeDividedDisk
3402 aShape = my3DPrimOperations->MakePrismDXDYDZ(aBaseShape,0.0,0.0,theH, -1.0);
3404 Handle(GEOM_Function) aFunction = aShape->GetLastFunction();
3405 aFunction->SetDescription(""); // Erase dump of MakePrismDXDYDZ
3406 aShape->SetType(GEOM_DIVIDEDCYLINDER);
3408 std::string aPatternStr;
3413 aPatternStr = "GEOM.SQUARE";
3416 aPatternStr = "GEOM.HEXAGON";
3420 //Make a Python command
3421 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedCylinder(" << theR << ", " << theH << ", " << aPatternStr.c_str() << ")";
3427 //=============================================================================
3429 * Create a smoothing surface from a set of points
3430 * \param thelPoints list of points or compounds of points
3431 * \param theNbMax maximum number of Bezier pieces in the resulting surface.
3432 * \param theDegMax maximum degree of the resulting BSpline surface
3433 * \param theDMax specifies maximum value of the GeomPlate_PlateG0Criterion criterion.
3434 * \return New GEOM_Object, containing the created shape.
3436 //=============================================================================
3437 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeSmoothingSurface (std::list<Handle(GEOM_Object)> thelPoints,
3445 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_SMOOTHINGSURFACE);
3447 //Add a new shape function with parameters
3448 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_SmoothingSurfaceDriver::GetID(), SMOOTHINGSURFACE_LPOINTS);
3449 if (aFunction.IsNull()) return NULL;
3451 //Check if the function is set correctly
3452 if (aFunction->GetDriverGUID() != AdvancedEngine_SmoothingSurfaceDriver::GetID()) return NULL;
3454 AdvancedEngine_ISmoothingSurface aData (aFunction);
3456 int aLen = thelPoints.size();
3457 aData.SetLength(aLen);
3459 std::list<Handle(GEOM_Object)>::iterator it = thelPoints.begin();
3460 for (; it != thelPoints.end(); it++, ind++) {
3461 Handle(GEOM_Function) aRefObj = (*it)->GetLastFunction();
3462 if (aRefObj.IsNull()) {
3463 SetErrorCode("NULL point or compound for bSplineFaceShape");
3466 aData.SetPntOrComp(ind, aRefObj);
3469 aData.SetNbMax(theNbMax);
3470 aData.SetDegMax(theDegMax);
3471 aData.SetDMax(theDMax);
3473 //Compute the resulting value
3475 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
3478 if (!GetSolver()->ComputeFunction(aFunction)) {
3479 SetErrorCode("SmoothingSurface driver failed");
3483 catch (Standard_Failure) {
3484 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3485 SetErrorCode(aFail->GetMessageString());
3489 //Make a Python command
3490 GEOM::TPythonDump pd (aFunction);
3491 pd << aShape << " = geompy.MakeSmoothingSurface([";
3492 it = thelPoints.begin();
3494 while (it != thelPoints.end()) {
3495 pd << ", " << (*it++);
3499 << theDegMax << ", "