1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // File : AdvancedEngine_IOperations.cxx
20 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
22 #include "AdvancedEngine_IOperations.hxx"
23 #include "AdvancedEngine_PipeTShapeDriver.hxx"
24 #include "AdvancedEngine_IPipeTShape.hxx"
25 #include "AdvancedEngine_DividedDiskDriver.hxx"
26 #include "AdvancedEngine_IDividedDisk.hxx"
27 #include "AdvancedEngine_SmoothingSurfaceDriver.hxx"
28 #include "AdvancedEngine_ISmoothingSurface.hxx"
30 #include <Basics_OCCTVersion.hxx>
32 #include <utilities.h>
34 #include <Utils_ExceptHandlers.hxx>
36 #include "GEOM_Function.hxx"
37 #include "GEOM_PythonDump.hxx"
38 #include "GEOMUtils.hxx"
39 #include "GEOMAlgo_Splitter.hxx"
40 #include "GEOMAlgo_FinderShapeOn1.hxx"
42 #include "GEOMImpl_Gen.hxx"
43 #include "GEOMImpl_Types.hxx"
45 #include "GEOMImpl_IBasicOperations.hxx"
46 #include "GEOMImpl_IBooleanOperations.hxx"
47 #include "GEOMImpl_IShapesOperations.hxx"
48 #include "GEOMImpl_ITransformOperations.hxx"
49 #include "GEOMImpl_IBlocksOperations.hxx"
50 #include "GEOMImpl_I3DPrimOperations.hxx"
51 #include "GEOMImpl_ILocalOperations.hxx"
52 #include "GEOMImpl_IHealingOperations.hxx"
53 #include "GEOMImpl_IGroupOperations.hxx"
54 #include "GEOMImpl_GlueDriver.hxx"
56 #include <TDF_Tool.hxx>
57 #include <TFunction_DriverTable.hxx>
58 #include <TFunction_Driver.hxx>
59 #include <TFunction_Logbook.hxx>
60 #include <TNaming_CopyShape.hxx>
63 #include <TopExp_Explorer.hxx>
65 #include <TopoDS_Vertex.hxx>
66 #include <TopTools_IndexedMapOfShape.hxx>
67 #include <TopTools_ListIteratorOfListOfShape.hxx>
68 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
70 #include <BRep_Builder.hxx>
71 #include <BRep_Tool.hxx>
73 #include <BRepAdaptor_Surface.hxx>
74 #include <BRepAlgoAPI_Cut.hxx>
75 #include <BRepAlgoAPI_Fuse.hxx>
76 #include <BRepBuilderAPI_MakeFace.hxx>
77 #include <BRepBuilderAPI_MakeVertex.hxx>
78 #include <BRepBuilderAPI_Transform.hxx>
79 #include <BRepPrimAPI_MakeCone.hxx>
80 #include <BRepPrimAPI_MakeCylinder.hxx>
86 #include <GC_MakeConicalSurface.hxx>
87 #include <Geom_CylindricalSurface.hxx>
89 #include <ShapeAnalysis_Edge.hxx>
93 #include "AdvancedEngine_Types.hxx"
95 #include <Standard_Stream.hxx>
96 #include <Standard_Failure.hxx>
97 #include <StdFail_NotDone.hxx>
98 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
100 #define HALF_LENGTH_MAIN_PIPE "Main pipe half length" //"Tuyau principal - demi longueur"
101 #define HALF_LENGTH_INCIDENT_PIPE "Incident pipe half length" //"Tuyau incident - demi longueur"
102 #define CIRCULAR_QUARTER_PIPE "Circular quarter of pipe" //"Circulaire - quart de tuyau"
103 #define THICKNESS "Thickness" //"Epaisseur"
104 #define FLANGE "Flange" // "Collerette"
105 #define CHAMFER_OR_FILLET "Chamfer or fillet" //"Chanfrein ou Raccord"
106 #define JUNCTION_FACE_1 "Junction 1" //"Face de jonction 1"
107 #define JUNCTION_FACE_2 "Junction 2" //"Face de jonction 2"
108 #define JUNCTION_FACE_3 "Junction 3" //"Face de jonction 3"
110 #define FIND_GROUPS_BY_POINTS 1
112 //=============================================================================
116 //=============================================================================
117 AdvancedEngine_IOperations::AdvancedEngine_IOperations(GEOM_Engine* theEngine, int theDocID) :
118 GEOM_IOperations(theEngine, theDocID)
120 MESSAGE("AdvancedEngine_IOperations::AdvancedEngine_IOperations");
121 myBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
122 myBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
123 myShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
124 myTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
125 myBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
126 my3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
127 myLocalOperations = new GEOMImpl_ILocalOperations(GetEngine(), GetDocID());
128 myHealingOperations = new GEOMImpl_IHealingOperations(GetEngine(), GetDocID());
129 myGroupOperations = new GEOMImpl_IGroupOperations(GetEngine(), GetDocID());
132 //=============================================================================
136 //=============================================================================
137 AdvancedEngine_IOperations::~AdvancedEngine_IOperations()
139 MESSAGE("AdvancedEngine_IOperations::~AdvancedEngine_IOperations");
140 delete myBasicOperations;
141 delete myBooleanOperations;
142 delete myShapesOperations;
143 delete myTransformOperations;
144 delete myBlocksOperations;
145 delete my3DPrimOperations;
146 delete myLocalOperations;
147 delete myHealingOperations;
148 delete myGroupOperations;
151 //=============================================================================
155 //=============================================================================
156 gp_Trsf AdvancedEngine_IOperations::GetPositionTrsf(double theL1, double theL2,
157 Handle(GEOM_Object) theP1,
158 Handle(GEOM_Object) theP2,
159 Handle(GEOM_Object) theP3)
161 // Old Local Coordinates System oldLCS
163 gp_Pnt P1(-theL1, 0, 0);
164 gp_Pnt P2(theL1, 0, 0);
165 gp_Pnt P3(0, 0, theL2);
167 gp_Dir oldX(gp_Vec(P1, P2));
168 gp_Dir oldZ(gp_Vec(P0, P3));
169 gp_Ax3 oldLCS(P0, oldZ, oldX);
171 // New Local Coordinates System newLCS
172 double LocX, LocY, LocZ;
173 gp_Pnt newP1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
174 gp_Pnt newP2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
175 gp_Pnt newP3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
176 LocX = (newP1.X() + newP2.X()) / 2.;
177 LocY = (newP1.Y() + newP2.Y()) / 2.;
178 LocZ = (newP1.Z() + newP2.Z()) / 2.;
179 gp_Pnt newO(LocX, LocY, LocZ);
181 gp_Dir newX(gp_Vec(newP1, newP2)); // P1P2 Vector
182 gp_Dir newZ(gp_Vec(newO, newP3)); // OP3 Vector
183 gp_Ax3 newLCS = gp_Ax3(newO, newZ, newX);
186 aTrsf.SetDisplacement(oldLCS, newLCS);
191 //=============================================================================
193 * CheckCompatiblePosition
196 //=============================================================================
197 bool AdvancedEngine_IOperations::CheckCompatiblePosition(double& theL1, double& theL2,
198 Handle(GEOM_Object) theP1,
199 Handle(GEOM_Object) theP2,
200 Handle(GEOM_Object) theP3,
204 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
205 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
206 gp_Pnt P3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
208 double d12 = P1.Distance(P2);
209 double d13 = P1.Distance(P3);
210 double d23 = P2.Distance(P3);
211 // double d2 = newO.Distance(P3);
213 if (Abs(d12) <= Precision::Confusion()) {
214 SetErrorCode("Junctions points P1 and P2 are identical");
217 if (Abs(d13) <= Precision::Confusion()) {
218 SetErrorCode("Junctions points P1 and P3 are identical");
221 if (Abs(d23) <= Precision::Confusion()) {
222 SetErrorCode("Junctions points P2 and P3 are identical");
227 double newL1 = 0.5 * d12;
228 double newL2 = sqrt(pow(d13,2)-pow(newL1,2));
230 // theL1*(1-theTolerance) <= newL1 <= theL1*(1+theTolerance)
232 if (fabs(newL1 - theL1) > Precision::Approximation()) {
233 if ( (newL1 * (1 - theTolerance) -theL1 <= Precision::Approximation()) &&
234 (newL1 * (1 + theTolerance) -theL1 >= Precision::Approximation()) ) {
235 // std::cerr << "theL1 = newL1" << std::endl;
239 SetErrorCode("Dimension for main pipe (L1) is incompatible with new position");
245 // theL2*(1-theTolerance) <= newL2 <= theL2*(1+theTolerance)
247 if (fabs(newL2 - theL2) > Precision::Approximation()) {
248 if ( (newL2 * (1 - theTolerance) -theL2 <= Precision::Approximation()) &&
249 (newL2 * (1 + theTolerance) -theL2 >= Precision::Approximation()) ) {
253 SetErrorCode("Dimension for incident pipe (L2) is incompatible with new position");
263 //=============================================================================
265 * Generate the propagation groups of a Pipe T-Shape used for hexa mesh
267 //=============================================================================
268 bool AdvancedEngine_IOperations::MakeGroups(Handle(GEOM_Object) theShape, int shapeType,
269 double theR1, double theW1, double theL1,
270 double theR2, double theW2, double theL2,
271 double theH, double theW, double theRF,
272 Handle(TColStd_HSequenceOfTransient) theSeq,
277 if (theShape.IsNull()) return false;
279 TopoDS_Shape aShape = theShape->GetValue();
280 if (aShape.IsNull()) {
281 SetErrorCode("Shape is not defined");
285 gp_Trsf aTrsfInv = aTrsf.Inverted();
287 // int expectedGroups = 0;
288 // if (shapeType == TSHAPE_BASIC)
289 // if (Abs(theR2+theW2-theR1-theW1) <= Precision::Approximation())
290 // expectedGroups = 10;
292 // expectedGroups = 11;
293 // else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET)
294 // expectedGroups = 12;
296 double aR1Ext = theR1 + theW1;
297 double aR2Ext = theR2 + theW2;
299 /////////////////////////
300 //// Groups of Faces ////
301 /////////////////////////
304 // Comment the following lines when GetInPlace bug is solved
306 // Workaround of GetInPlace bug
307 // Create a bounding box that fits the shape
308 Handle(GEOM_Object) aBox = my3DPrimOperations->MakeBoxDXDYDZ(2*theL1, 2*aR1Ext, aR1Ext+theL2);
309 aBox->GetLastFunction()->SetDescription("");
310 myTransformOperations->TranslateDXDYDZ(aBox, -theL1, -aR1Ext, -aR1Ext);
311 aBox->GetLastFunction()->SetDescription("");
312 // Apply transformation to box
313 BRepBuilderAPI_Transform aTransformationBox(aBox->GetValue(), aTrsf, Standard_False);
314 TopoDS_Shape aBoxShapeTrsf = aTransformationBox.Shape();
315 aBox->GetLastFunction()->SetValue(aBoxShapeTrsf);
317 // Get the shell of the box
318 Handle(GEOM_Object) aShell = Handle(GEOM_Object)::DownCast
319 (myShapesOperations->MakeExplode(aBox, TopAbs_SHELL, true)->Value(1));
320 aBox->GetLastFunction()->SetDescription("");
321 aShell->GetLastFunction()->SetDescription("");
322 // Get the common shapes between shell and shape
323 Handle(GEOM_Object) aCommonCompound = myBooleanOperations->MakeBoolean
324 (theShape, aShell, 1, Standard_False); // MakeCommon
325 if (aCommonCompound.IsNull()) {
326 SetErrorCode(myBooleanOperations->GetErrorCode());
329 aCommonCompound->GetLastFunction()->SetDescription("");
330 // Explode the faces of common shapes => 3 faces
331 Handle(TColStd_HSequenceOfTransient) aCommonFaces =
332 myShapesOperations->MakeExplode(aCommonCompound, TopAbs_FACE, true);
333 aCommonCompound->GetLastFunction()->SetDescription("");
334 std::list<Handle(GEOM_Object)> aCompoundOfFacesList;
336 for (int i=0 ; i<= aCommonFaces->Length()-4 ; i+=4) {
337 std::list<Handle(GEOM_Object)> aFacesList;
338 for (int j = 1 ; j <= 4 ; j++) {
339 Handle(GEOM_Object) aFace = Handle(GEOM_Object)::DownCast(aCommonFaces->Value(i+j)); // Junction faces
340 if (!aFace.IsNull()) {
341 aFace->GetLastFunction()->SetDescription("");
342 aFacesList.push_back(aFace);
345 Handle(GEOM_Object) aCompoundOfFaces = myShapesOperations->MakeCompound(aFacesList);
346 if (!aCompoundOfFaces.IsNull()) {
347 aCompoundOfFaces->GetLastFunction()->SetDescription("");
348 aCompoundOfFacesList.push_back(aCompoundOfFaces);
352 if (aCompoundOfFacesList.size() == 3) {
353 Handle(GEOM_Object) aPln1 = aCompoundOfFacesList.front();
354 aCompoundOfFacesList.pop_front();
355 Handle(GEOM_Object) aPln2 = aCompoundOfFacesList.front();
356 aCompoundOfFacesList.pop_front();
357 Handle(GEOM_Object) aPln3 = aCompoundOfFacesList.front();
358 aCompoundOfFacesList.pop_front();
363 // Uncomment the following lines when GetInPlace bug is solved
365 // Handle(GEOM_Object) aP1 = myBasicOperations->MakePointXYZ(-theL1, 0, 0);
366 // Handle(GEOM_Object) aP2 = myBasicOperations->MakePointXYZ(-0, 0, theL2);
367 // Handle(GEOM_Object) aP3 = myBasicOperations->MakePointXYZ(theL1, 0, 0);
368 // aP1->GetLastFunction()->SetDescription("");
369 // aP2->GetLastFunction()->SetDescription("");
370 // aP3->GetLastFunction()->SetDescription("");
371 // Handle(GEOM_Object) aV1 = myBasicOperations->MakeVectorDXDYDZ(-1, 0, 0);
372 // Handle(GEOM_Object) aV2 = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
373 // Handle(GEOM_Object) aV3 = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
374 // aV1->GetLastFunction()->SetDescription("");
375 // aV2->GetLastFunction()->SetDescription("");
376 // aV3->GetLastFunction()->SetDescription("");
377 // Handle(GEOM_Object) aPln1 = myBasicOperations->MakePlanePntVec(aP1, aV1, 2*(aR1Ext+theL2));
378 // Handle(GEOM_Object) aPln2 = myBasicOperations->MakePlanePntVec(aP2, aV2, 2*(aR2Ext));
379 // Handle(GEOM_Object) aPln3 = myBasicOperations->MakePlanePntVec(aP3, aV3, 2*(aR1Ext+theL2));
380 // aPln1->GetLastFunction()->SetDescription("");
381 // aPln2->GetLastFunction()->SetDescription("");
382 // aPln3->GetLastFunction()->SetDescription("");
384 // BRepBuilderAPI_Transform aTransformation1(aPln1->GetValue(), aTrsf, Standard_False);
385 // TopoDS_Shape aTrsf_Shape1 = aTransformation1.Shape();
386 // aPln1->GetLastFunction()->SetValue(aTrsf_Shape1);
387 // BRepBuilderAPI_Transform aTransformation2(aPln2->GetValue(), aTrsf, Standard_False);
388 // TopoDS_Shape aTrsf_Shape2 = aTransformation2.Shape();
389 // aPln2->GetLastFunction()->SetValue(aTrsf_Shape2);
390 // BRepBuilderAPI_Transform aTransformation3(aPln3->GetValue(), aTrsf, Standard_False);
391 // TopoDS_Shape aTrsf_Shape3 = aTransformation3.Shape();
392 // aPln3->GetLastFunction()->SetValue(aTrsf_Shape3);
396 Handle(GEOM_Object) junctionFaces1 = myShapesOperations->GetInPlace(theShape, aPln1);
397 if (junctionFaces1.IsNull())
398 junctionFaces1 = myShapesOperations->GetShapesOnShapeAsCompound
399 (aPln1, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
400 if (!junctionFaces1.IsNull()) {
401 junctionFaces1->GetLastFunction()->SetDescription("");
402 junctionFaces1->SetName("JUNCTION_FACE_1");
403 theSeq->Append(junctionFaces1);
406 SetErrorCode("Junction face 1 not found");
407 // theSeq->Append(aPln1);
410 Handle(GEOM_Object) junctionFaces2 = myShapesOperations->GetInPlace(theShape, aPln2);
411 if (junctionFaces2.IsNull())
412 junctionFaces2 = myShapesOperations->GetShapesOnShapeAsCompound
413 (aPln2, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
414 if (!junctionFaces2.IsNull()) {
415 junctionFaces2->GetLastFunction()->SetDescription("");
416 junctionFaces2->SetName("JUNCTION_FACE_2");
417 theSeq->Append(junctionFaces2);
420 SetErrorCode("Junction face 2 not found");
421 // theSeq->Append(aPln2);
424 Handle(GEOM_Object) junctionFaces3 = myShapesOperations->GetInPlace(theShape, aPln3);
425 if (junctionFaces3.IsNull())
426 junctionFaces3 = myShapesOperations->GetShapesOnShapeAsCompound
427 (aPln3, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
428 if (!junctionFaces3.IsNull()) {
429 junctionFaces3->GetLastFunction()->SetDescription("");
430 junctionFaces3->SetName("JUNCTION_FACE_3");
431 theSeq->Append(junctionFaces3);
434 SetErrorCode("Junction face 3 not found");
435 // theSeq->Append(aPln3);
438 // Comment the following lines when GetInPlace bug is solved
443 /////////////////////////
444 //// Groups of Edges ////
445 /////////////////////////
446 // Result of propagate
448 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
450 TCollection_AsciiString theDesc = aFunction->GetDescription();
451 Handle(TColStd_HSequenceOfTransient) aSeqPropagate = myBlocksOperations->Propagate(theShape);
452 if (aSeqPropagate.IsNull() || aSeqPropagate->Length() == 0) {
453 SetErrorCode("Propagation groups not found");
456 Standard_Integer aNbGroups = aSeqPropagate->Length();
457 // Recover previous description to get rid of Propagate dump
458 aFunction->SetDescription(theDesc);
460 #ifdef FIND_GROUPS_BY_POINTS
461 // BEGIN: new groups search
468 // g / ''..| | |..'' \
470 // .---.--'.. | | | ..'--.---.
471 // |a \ '''...........''' / |
472 // |-------\------' | '------/-------.
477 // ._________________|_________________.
483 // |-----------------|-----------------|
485 // '-----------------'-----------------'
488 // "Thickness" group (a)
489 gp_Pnt aPntA (-theL1, 0, theR1 + theW1/2.);
490 aPntA.Transform(aTrsf);
491 BRepBuilderAPI_MakeVertex mkVertexA (aPntA);
492 TopoDS_Vertex aVertA = TopoDS::Vertex(mkVertexA.Shape());
493 TopoDS_Shape anEdgeA = GEOMUtils::GetEdgeNearPoint(aShape, aVertA);
495 // "Circular quarter of pipe" group (b)
496 gp_Pnt aPntB (-theL1, -aR1Ext * sin(M_PI/4.), -aR1Ext * sin(M_PI/4.));
497 aPntB.Transform(aTrsf);
498 BRepBuilderAPI_MakeVertex mkVertexB (aPntB);
499 TopoDS_Vertex aVertB = TopoDS::Vertex(mkVertexB.Shape());
500 TopoDS_Shape anEdgeB = GEOMUtils::GetEdgeNearPoint(aShape, aVertB);
502 // "Circular quarter of pipe" group (c)
503 gp_Pnt aPntC (-theL1, -aR1Ext * sin(M_PI/4.), aR1Ext * sin(M_PI/4.));
504 aPntC.Transform(aTrsf);
505 BRepBuilderAPI_MakeVertex mkVertexC (aPntC);
506 TopoDS_Vertex aVertC = TopoDS::Vertex(mkVertexC.Shape());
507 TopoDS_Shape anEdgeC = GEOMUtils::GetEdgeNearPoint(aShape, aVertC);
509 // "Main pipe half length" group (d)
510 gp_Pnt aPntD (-theL1/2., 0, -aR1Ext);
511 aPntD.Transform(aTrsf);
512 BRepBuilderAPI_MakeVertex mkVertexD (aPntD);
513 TopoDS_Vertex aVertD = TopoDS::Vertex(mkVertexD.Shape());
514 TopoDS_Shape anEdgeD = GEOMUtils::GetEdgeNearPoint(aShape, aVertD);
516 // "Incident pipe half length" group (e)
517 double aTol10 = Precision::Confusion() * 10.;
518 gp_Pnt aPntE (-aR2Ext, 0, theL2 - aTol10);
519 aPntE.Transform(aTrsf);
520 BRepBuilderAPI_MakeVertex mkVertexE (aPntE);
521 TopoDS_Vertex aVertE = TopoDS::Vertex(mkVertexE.Shape());
522 TopoDS_Shape anEdgeE = GEOMUtils::GetEdgeNearPoint(aShape, aVertE);
524 // "Flange" group (f)
525 double aFx = - aR2Ext - aTol10;
526 if (shapeType == TSHAPE_CHAMFER)
528 else if (shapeType == TSHAPE_FILLET)
530 gp_Pnt aPntF (aFx, 0, aR1Ext);
531 aPntF.Transform(aTrsf);
532 BRepBuilderAPI_MakeVertex mkVertexF (aPntF);
533 TopoDS_Vertex aVertF = TopoDS::Vertex(mkVertexF.Shape());
534 TopoDS_Shape anEdgeF = GEOMUtils::GetEdgeNearPoint(aShape, aVertF);
536 // "Chamfer or Fillet" group (g)
537 TopoDS_Shape anEdgeG;
538 if (shapeType == TSHAPE_CHAMFER) {
539 gp_Pnt aPntG (-aR2Ext - theW/2., 0, aR1Ext + theH/2.);
540 aPntG.Transform(aTrsf);
541 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
542 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
543 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
545 else if (shapeType == TSHAPE_FILLET) {
546 gp_Pnt aPntG (-aR2Ext - theRF/2., 0, aR1Ext + theRF/2.);
547 aPntG.Transform(aTrsf);
548 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
549 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
550 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
553 for (int i = 1 ; i <= aNbGroups; i++) {
554 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
558 TopoDS_Shape aGroupShape = aGroup->GetValue();
559 TopTools_IndexedMapOfShape anEdgesMap;
560 TopExp::MapShapes(aGroupShape, TopAbs_EDGE, anEdgesMap);
562 if (anEdgesMap.Contains(anEdgeA)) { // a
563 aGroup->SetName("THICKNESS");
564 theSeq->Append(aGroup);
566 else if (anEdgesMap.Contains(anEdgeB)) { // b
567 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
568 theSeq->Append(aGroup);
570 else if (anEdgesMap.Contains(anEdgeC)) { // c
571 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
572 theSeq->Append(aGroup);
574 else if (anEdgesMap.Contains(anEdgeD)) { // d
575 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
576 theSeq->Append(aGroup);
578 else if (anEdgesMap.Contains(anEdgeE)) { // e
579 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
580 theSeq->Append(aGroup);
582 else if (anEdgesMap.Contains(anEdgeF)) { // f
583 aGroup->SetName("FLANGE");
584 theSeq->Append(aGroup);
586 else if (shapeType == TSHAPE_CHAMFER) { // g
587 if (anEdgesMap.Contains(anEdgeG)) {
588 aGroup->SetName("CHAMFER");
589 theSeq->Append(aGroup);
592 else if (shapeType == TSHAPE_FILLET) { // g
593 if (anEdgesMap.Contains(anEdgeG)) {
594 aGroup->SetName("FILLET");
595 theSeq->Append(aGroup);
601 // END: new groups search
604 bool circularFoundAndAdded = false;
605 bool circularFound10 = false;
606 bool incidentPipeFound = false;
607 bool mainPipeFound = false;
608 bool mainPipeFoundAndAdded = false;
609 bool radialFound =false;
610 bool flangeFound = false;
611 bool flangeFoundAndAdded = false;
612 bool chamferOrFilletFound = false;
614 for (int i = 1 ; i <= aNbGroups; i++) {
617 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
621 TopoDS_Shape aGroupShape = aGroup->GetValue();
622 BRepBuilderAPI_Transform aTransformationShapeInv (aGroupShape, aTrsfInv, Standard_False);
623 TopoDS_Shape aGroupShapeTrsfInv = aTransformationShapeInv.Shape();
625 TopTools_IndexedMapOfShape anEdgesMap;
626 TopExp::MapShapes(aGroupShapeTrsfInv,TopAbs_EDGE, anEdgesMap);
627 Standard_Integer nbEdges = anEdgesMap.Extent();
629 if (shapeType == TSHAPE_BASIC) {
630 if ((nbEdges >= 21) || /*R1Ext = R2Ext*/(nbEdges == 17)) { // 17, 17+8*{1,2,3}, 21, 21+8*{1,2,3}
632 aGroup->SetName("THICKNESS");
634 else if (nbEdges == 6) {
635 if (!circularFoundAndAdded) {
636 circularFoundAndAdded = true;
638 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
641 else if (nbEdges == 8) {
642 incidentPipeFound = true;
643 mainPipeFound = false;
647 TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
649 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
650 double x=aP.X(), y=aP.Y(), z=aP.Z();
653 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
654 (Abs(y) > aR2Ext + Precision::Confusion())) {
655 incidentPipeFound = false;
658 if ( z < -Precision::Confusion()) {
659 // length of main pipe
660 mainPipeFound = true;
661 if (!mainPipeFoundAndAdded) {
662 mainPipeFoundAndAdded = true;
664 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
668 else if (Abs(x) > (theL1-Precision::Confusion())) {
669 // discretisation circulaire
671 if (!circularFoundAndAdded) {
672 circularFoundAndAdded = true;
674 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
679 if (incidentPipeFound) {
681 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
683 if (!addGroup && (!incidentPipeFound &&
687 // Flange (collerette)
690 aGroup->SetName("FLANGE");
696 else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
697 if (nbEdges >= 25) { // 25, 25+8, 25+16, 25+24
699 aGroup->SetName("THICKNESS");
701 else if ((nbEdges == 10) || (nbEdges == 6)) {
702 if (!circularFoundAndAdded) {
704 circularFoundAndAdded = true;
705 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
707 circularFound10 = true;
710 else if (!circularFound10 && nbEdges == 10) {
711 circularFound10 = true;
713 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
716 else if (nbEdges == 8) {
717 incidentPipeFound = true;
718 mainPipeFound = true;
721 bool isNearZ0 = false;
722 bool isBelowZ0 = false;
724 TopExp_Explorer Ex (aGroupShapeTrsfInv,TopAbs_VERTEX);
726 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
727 double x=aP.X(), y=aP.Y(), z=aP.Z();
729 // tuy_princ_long_avant & tuy_princ_long_apres
730 //bool isMain = (((z < Precision::Confusion()) || (x < Precision::Confusion())) &&
731 // ((y <= aR1Ext + Precision::Confusion()) ||
732 // (y <= -(aR1Ext + Precision::Confusion())) ||
733 // (y <= theR1 + Precision::Confusion()) ||
734 // (y == -(theR1 + Precision::Confusion()))));
735 bool isMain = ((z < Precision::Confusion() || x < Precision::Confusion()) &&
736 (fabs(y) > theR1 - Precision::Confusion() ||
737 fabs(y) < Precision::Confusion()));
740 mainPipeFound = false;
744 //if (z < Precision::Confusion() && !isMain) {
745 // flangeFound = true;
746 // if (!flangeFoundAndAdded) {
747 // flangeFoundAndAdded = true;
749 // aGroup->SetName("FLANGE");
752 if (fabs(z) < Precision::Confusion()) isNearZ0 = true;
753 if (z < - Precision::Confusion()) isBelowZ0 = true;
756 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
757 (Abs(y) > aR2Ext + Precision::Confusion())) {
758 incidentPipeFound = false;
764 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
766 if (incidentPipeFound) {
768 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
770 if (isNearZ0 && !isBelowZ0) {
772 if (!flangeFoundAndAdded) {
773 flangeFoundAndAdded = true;
775 aGroup->SetName("FLANGE");
778 if (!addGroup && (!incidentPipeFound &&
781 !chamferOrFilletFound)) {
783 chamferOrFilletFound = true;
784 if (shapeType == TSHAPE_CHAMFER)
785 aGroup->SetName("CHAMFER");
787 aGroup->SetName("FILLET");
793 // Add group to the list
795 theSeq->Append(aGroup);
803 //=============================================================================
805 * Return faces that are laying on surface.
807 //=============================================================================
808 bool AdvancedEngine_IOperations::GetFacesOnSurf
809 (const TopoDS_Shape &theShape,
810 const Handle_Geom_Surface& theSurface,
811 const Standard_Real theTolerance,
812 TopTools_ListOfShape &theFaces)
814 GEOMAlgo_FinderShapeOn1 aFinder;
816 aFinder.SetShape(theShape);
817 aFinder.SetTolerance(theTolerance);
818 aFinder.SetSurface(theSurface);
819 aFinder.SetShapeType(TopAbs_FACE);
820 aFinder.SetState(GEOMAlgo_ST_ON);
822 // Sets the minimal number of inner points for the faces that do not have own
823 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
825 aFinder.SetNbPntsMin(3);
826 // Sets the maximal number of inner points for edges or faces.
827 // It is usefull for the cases when this number is very big (e.g =2000) to improve
828 // the performance. If this value =0, all inner points will be taken into account.
830 aFinder.SetNbPntsMax(100);
833 // Interprete results
834 Standard_Integer iErr = aFinder.ErrorStatus();
835 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
837 MESSAGE(" iErr : " << iErr);
838 TCollection_AsciiString aMsg (" iErr : ");
839 aMsg += TCollection_AsciiString(iErr);
843 Standard_Integer iWrn = aFinder.WarningStatus();
844 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
846 MESSAGE(" *** iWrn : " << iWrn);
849 const TopTools_ListOfShape &aListRes = aFinder.Shapes(); // the result
850 TopTools_ListIteratorOfListOfShape anIter (aListRes);
852 for (; anIter.More(); anIter.Next()) {
853 theFaces.Append(anIter.Value());
859 //=============================================================================
861 * Creates and returns conical face.
863 //=============================================================================
864 TopoDS_Shape AdvancedEngine_IOperations::MakeConicalFace
865 (const gp_Ax2 &theAxis,
866 const double theRadius,
867 const double theRadiusThin,
868 const double theHeight,
869 const gp_Trsf &theTrsf)
871 BRepPrimAPI_MakeCone aMkCone (theAxis, theRadius, theRadiusThin, theHeight);
872 TopoDS_Shape aResult;
875 if (aMkCone.IsDone()) {
876 TopExp_Explorer anExp(aMkCone.Shape(), TopAbs_FACE);
878 for (; anExp.More(); anExp.Next()) {
879 TopoDS_Face aFace = TopoDS::Face(anExp.Current());
881 if (aFace.IsNull() == Standard_False) {
882 BRepAdaptor_Surface anAdaptor(aFace, Standard_False);
884 if (anAdaptor.GetType() == GeomAbs_Cone) {
885 // This is a conical face. Transform and return it.
886 BRepBuilderAPI_Transform aTransf(aFace, theTrsf, Standard_False);
888 aResult = aTransf.Shape();
898 //=============================================================================
900 * Generate the internal group of a Pipe T-Shape
902 //=============================================================================
903 bool AdvancedEngine_IOperations::MakeInternalGroup
904 (const Handle(GEOM_Object) &theShape,
905 const double theR1, const double theLen1,
906 const double theR2, const double theLen2,
907 const double theRL, double theTransLenL,
908 const double theRR, double theTransLenR,
909 const double theRI, double theTransLenI,
910 const Handle(TColStd_HSequenceOfTransient) &theSeq,
911 const gp_Trsf &theTrsf)
915 if (theShape.IsNull()) {
919 TopoDS_Shape aShape = theShape->GetValue();
921 if (aShape.IsNull()) {
922 SetErrorCode("Shape is not defined");
927 Standard_Real aMaxTol = -RealLast();
928 TopExp_Explorer anExp(aShape, TopAbs_VERTEX);
930 for (; anExp.More(); anExp.Next()) {
931 TopoDS_Vertex aVertex = TopoDS::Vertex(anExp.Current());
933 if (aVertex.IsNull() == Standard_False) {
934 const Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
936 if (aTol > aMaxTol) {
942 // Construct internal surfaces.
943 Standard_Integer i = 0;
944 const Standard_Integer aMaxNbSurf = 5;
945 Handle(Geom_Surface) aSurface[aMaxNbSurf];
946 TopTools_ListOfShape aConicalFaces;
947 Standard_Real aTolConf = Precision::Confusion();
949 // 1. Construct the internal surface of main pipe.
950 gp_Ax2 anAxis1 (gp::Origin(), gp::DX(), gp::DZ());
951 gp_Ax2 anAxis2 (gp::Origin(), gp::DZ(), gp::DX());
953 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theR1);
955 // 2. Construct the internal surface of incident pipe.
956 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theR2);
958 // 3. Construct the internal surface of left reduction pipe.
959 if (theRL > aTolConf) {
960 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRL);
962 if (theTransLenL > aTolConf) {
963 // 3.1. Construct the internal surface of left transition pipe.
964 gp_Pnt aPLeft (-theLen1, 0., 0.);
965 gp_Ax2 anAxisLeft (aPLeft, -gp::DX(), gp::DZ());
966 TopoDS_Shape aConeLeft =
967 MakeConicalFace(anAxisLeft, theR1, theRL, theTransLenL, theTrsf);
969 if (aConeLeft.IsNull() == Standard_False) {
970 aConicalFaces.Append(aConeLeft);
975 // 4. Construct the internal surface of right reduction pipe.
976 if (theRR > aTolConf) {
977 // There is no need to construct another cylinder of the same radius. Skip it.
978 if (Abs(theRR - theRL) > aTolConf) {
979 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRR);
982 if (theTransLenL > aTolConf) {
983 // 4.1. Construct the internal surface of right transition pipe.
984 gp_Pnt aPRight (theLen1, 0., 0.);
985 gp_Ax2 anAxisRight (aPRight, gp::DX(), gp::DZ());
986 TopoDS_Shape aConeRight =
987 MakeConicalFace(anAxisRight, theR1, theRR, theTransLenR, theTrsf);
989 if (aConeRight.IsNull() == Standard_False) {
990 aConicalFaces.Append(aConeRight);
995 // 5. Construct the internal surface of incident reduction pipe.
996 if (theRI > aTolConf) {
997 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theRI);
999 if (theTransLenI > aTolConf) {
1000 // 5.1. Construct the internal surface of incident transition pipe.
1001 gp_Pnt aPInci (0., 0., theLen2);
1002 gp_Ax2 anAxisInci (aPInci, gp::DZ(), gp::DX());
1003 TopoDS_Shape aConeInci =
1004 MakeConicalFace(anAxisInci, theR2, theRI, theTransLenI, theTrsf);
1006 if (aConeInci.IsNull() == Standard_False) {
1007 aConicalFaces.Append(aConeInci);
1012 // Get faces that are laying on cylindrical surfaces.
1013 TopTools_ListOfShape aFaces;
1014 gp_Trsf anInvTrsf = theTrsf.Inverted();
1016 for (i = 0; i < aMaxNbSurf; i++) {
1017 if (aSurface[i].IsNull()) {
1021 aSurface[i]->Transform(theTrsf);
1023 TopTools_ListOfShape aLocalFaces;
1025 if (!GetFacesOnSurf(aShape, aSurface[i], aMaxTol, aLocalFaces)) {
1030 // Check if the result contains outer cylinders.
1031 // It is required for main and incident pipes.
1032 TopTools_ListIteratorOfListOfShape anIter(aLocalFaces);
1034 while (anIter.More()) {
1035 TopExp_Explorer anExp(anIter.Value(), TopAbs_VERTEX);
1036 Standard_Boolean isInside = Standard_False;
1038 // Get a vertex from this shape
1040 TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
1042 if (aVtx.IsNull() == Standard_False) {
1043 gp_Pnt aPnt = BRep_Tool::Pnt(aVtx);
1045 aPnt.Transform(anInvTrsf);
1048 // Check if the point is inside the main pipe.
1049 isInside = (Abs(aPnt.X()) <= theLen1);
1051 // Check if the point is inside the incident pipe.
1052 isInside = (aPnt.Z() <= theLen2);
1061 // Remove this face.
1062 aLocalFaces.Remove(anIter);
1067 aFaces.Append(aLocalFaces);
1070 // Get faces that are laying on conical faces.
1071 if (aConicalFaces.IsEmpty() == Standard_False) {
1072 Handle(GEOM_Object) aCone =
1073 GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1074 Handle(GEOM_Function) aFunction =
1075 aCone->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1076 TopTools_ListIteratorOfListOfShape aFIter(aConicalFaces);
1077 Handle(GEOM_Object) aConeFromShape;
1079 for (; aFIter.More(); aFIter.Next()) {
1080 aFunction->SetValue(aFIter.Value());
1081 aConeFromShape = myShapesOperations->GetInPlace(theShape, aCone);
1083 if (aConeFromShape.IsNull() == Standard_False) {
1084 aConeFromShape->GetLastFunction()->SetDescription("");
1085 TopoDS_Shape aConeFaces = aConeFromShape->GetValue();
1086 TopExp_Explorer anExp(aConeFaces, TopAbs_FACE);
1088 for (; anExp.More(); anExp.Next()) {
1089 TopoDS_Face aConeFace = TopoDS::Face(anExp.Current());
1091 if (aConeFace.IsNull() == Standard_False) {
1092 aFaces.Append(aConeFace);
1099 // Create a group of internal faces.
1100 if (aFaces.IsEmpty() == Standard_False) {
1101 Handle(GEOM_Object) aGroup = myGroupOperations->CreateGroup(theShape, TopAbs_FACE);
1103 if (aGroup.IsNull() == Standard_False) {
1104 aGroup->GetLastFunction()->SetDescription("");
1105 aGroup->SetName("INTERNAL_FACES");
1107 TopTools_IndexedMapOfShape anIndices;
1108 Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger;
1110 TopExp::MapShapes(aShape, anIndices);
1112 TopTools_ListIteratorOfListOfShape anIter(aFaces);
1114 for (; anIter.More(); anIter.Next()) {
1115 const TopoDS_Shape &aFace = anIter.Value();
1116 const Standard_Integer anIndex = anIndices.FindIndex(aFace);
1119 aSeqIDs->Append(anIndex);
1123 myGroupOperations->UnionIDs(aGroup, aSeqIDs);
1124 aGroup->GetLastFunction()->SetDescription("");
1125 theSeq->Append(aGroup);
1134 bool AdvancedEngine_IOperations::MakePipeTShapePartition(Handle(GEOM_Object) theShape,
1135 double theR1, double theW1, double theL1,
1136 double theR2, double theW2, double theL2,
1137 double theH, double theW,
1138 double theRF, bool isNormal)
1142 // Build tools for partition operation:
1143 // 1 face and 2 planes
1145 Handle(GEOM_Object) arete_intersect_int, arete_intersect_ext;
1146 Handle(GEOM_Object) wire_t, wire_t2, face_t, face_t2;
1147 Handle(GEOM_Object) chan_racc;
1148 Handle(GEOM_Object) vi1, vi2;
1149 Handle(GEOM_Object) Te3;
1153 Handle(GEOM_Object) Vector_Z = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1154 Vector_Z->GetLastFunction()->SetDescription("");
1157 double aSize = 2*(theL1 + theL2);
1158 double aR1Ext = theR1 + theW1;
1159 double aR2Ext = theR2 + theW2;
1160 double theVertCylinderRadius = aR2Ext + theW + theRF;
1161 double theHoriCylinderRadius = aR1Ext + theH + theRF;
1163 // Common edges on internal cylinder
1164 Handle(GEOM_Object) box_i = my3DPrimOperations->MakeBoxDXDYDZ(theR2, theR2, theR1);
1165 box_i->GetLastFunction()->SetDescription("");
1166 box_i = myTransformOperations->TranslateDXDYDZ(box_i, -theR2, -theR2, 0);
1167 box_i->GetLastFunction()->SetDescription("");
1169 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1170 TCollection_AsciiString theDesc = aFunction->GetDescription();
1171 Handle(TColStd_HSequenceOfTransient) edges_i =
1172 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1173 // Recover previous description to get rid of Propagate dump
1174 aFunction->SetDescription(theDesc);
1175 if (edges_i.IsNull() || edges_i->Length() == 0) {
1176 SetErrorCode("Internal edges not found");
1179 for (int i=1; i<=edges_i->Length();i++) {
1180 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_i->Value(i));
1181 anObj->GetLastFunction()->SetDescription("");
1183 arete_intersect_int = Handle(GEOM_Object)::DownCast(edges_i->Value(1));
1185 // search for vertices located on both internal pipes
1186 aFunction = theShape->GetLastFunction();
1187 theDesc = aFunction->GetDescription();
1188 Handle(TColStd_HSequenceOfTransient) vertices_i =
1189 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1190 // Recover previous description to get rid of Propagate dump
1191 aFunction->SetDescription(theDesc);
1192 if (vertices_i.IsNull() || vertices_i->Length() == 0) {
1193 SetErrorCode("Internal vertices not found");
1197 double d1min = theR2+theW2, d2min=theR2+theW2;
1198 for (int i = 1; i <= vertices_i->Length(); i++) {
1199 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_i->Value(i));
1200 v->GetLastFunction()->SetDescription("");
1201 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1202 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1203 if (Abs(aP.X()) <= Precision::Confusion()) {
1204 if (Abs(aP.Y()) < d1min) {
1206 d1min = Abs(aP.Y());
1208 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1209 if (Abs(aP.X()) < d2min) {
1211 d2min = Abs(aP.X());
1215 if (vi1.IsNull() || vi2.IsNull()) {
1216 SetErrorCode("Cannot find internal intersection vertices");
1220 std::list<Handle(GEOM_Object)> theShapes;
1223 Handle(GEOM_Object) ve1, ve2;
1224 TopoDS_Vertex vertex1, vertex2;
1226 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ(aR2Ext, aR2Ext, aR1Ext);
1227 box_e->GetLastFunction()->SetDescription("");
1228 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -aR2Ext, -aR2Ext, 0);
1229 box_e->GetLastFunction()->SetDescription("");
1231 // search for vertices located on both external pipes
1232 aFunction = theShape->GetLastFunction();
1233 theDesc = aFunction->GetDescription();
1234 Handle(TColStd_HSequenceOfTransient) vertices_e =
1235 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1236 // Recover previous description to get rid of Propagate dump
1237 aFunction->SetDescription(theDesc);
1238 if (vertices_e.IsNull() || vertices_e->Length() == 0) {
1239 SetErrorCode("External vertices not found");
1243 double d1max = 0, d2max = 0;
1244 for (int i = 1; i <= vertices_e->Length(); i++) {
1245 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_e->Value(i));
1246 v->GetLastFunction()->SetDescription("");
1247 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1248 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1249 if (Abs(aP.X()) <= Precision::Confusion()) {
1250 if (Abs(aP.Y()) > d1max) {
1253 d1max = Abs(aP.Y());
1255 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1256 if (Abs(aP.X()) > d2max) {
1259 d2max = Abs(aP.X());
1263 if (ve1.IsNull() || ve2.IsNull()) {
1264 SetErrorCode("Cannot find external intersection vertices");
1267 Handle(GEOM_Object) edge_e1, edge_e2;
1269 // Common edges on external cylinder
1270 aFunction = theShape->GetLastFunction();
1271 theDesc = aFunction->GetDescription();
1272 Handle(TColStd_HSequenceOfTransient) edges_e =
1273 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1274 // Recover previous description to get rid of Propagate dump
1275 aFunction->SetDescription(theDesc);
1276 if (edges_e.IsNull() || edges_e->Length() == 0) {
1277 SetErrorCode("External edges not found");
1280 ShapeAnalysis_Edge sae;
1281 for (int i=1; i<=edges_e->Length();i++) {
1282 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
1283 anObj->GetLastFunction()->SetDescription("");
1284 TopoDS_Edge anEdge = TopoDS::Edge(anObj->GetValue());
1285 if ( !anEdge.IsNull() &&
1286 (sae.FirstVertex(anEdge).IsSame(vertex1) || sae.LastVertex(anEdge).IsSame(vertex1)) &&
1287 (sae.FirstVertex(anEdge).IsSame(vertex2) || sae.LastVertex(anEdge).IsSame(vertex2))) {
1288 arete_intersect_ext = anObj;
1292 edge_e1 = myBasicOperations->MakeLineTwoPnt(ve1, vi1);
1293 if (edge_e1.IsNull()) {
1294 SetErrorCode("Edge 1 could not be built");
1298 edge_e2 = myBasicOperations->MakeLineTwoPnt(ve2, vi2);
1299 if (edge_e2.IsNull()) {
1300 SetErrorCode("Edge 2 could not be built");
1304 edge_e1->GetLastFunction()->SetDescription("");
1305 edge_e2->GetLastFunction()->SetDescription("");
1307 std::list<Handle(GEOM_Object)> edge_e_elist;
1308 edge_e_elist.push_back(arete_intersect_int);
1309 edge_e_elist.push_back(edge_e1);
1310 edge_e_elist.push_back(arete_intersect_ext);
1311 edge_e_elist.push_back(edge_e2);
1312 wire_t = myShapesOperations->MakeWire(edge_e_elist, 1e-7);
1313 if (wire_t.IsNull()) {
1314 SetErrorCode("Impossible to build wire");
1317 wire_t->GetLastFunction()->SetDescription("");
1318 face_t = myShapesOperations->MakeFace(wire_t, false);
1319 if (face_t.IsNull()) {
1320 SetErrorCode("Impossible to build face");
1323 face_t->GetLastFunction()->SetDescription("");
1325 theShapes.push_back(theShape);
1326 theShapes.push_back(vi1);
1327 theShapes.push_back(vi2);
1328 theShapes.push_back(ve1);
1329 theShapes.push_back(ve2);
1330 theShapes.push_back(edge_e1);
1331 theShapes.push_back(edge_e2);
1332 theShapes.push_back(wire_t);
1333 theShapes.push_back(face_t);
1336 Handle(GEOM_Object) P1, P2, P3, P4, P5, P6;
1337 int idP1, idP2, idP3, idP4;
1340 std::vector<int> LX;
1341 std::vector<int> LY;
1342 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ
1343 (theVertCylinderRadius, theVertCylinderRadius, theHoriCylinderRadius);
1344 box_e->GetLastFunction()->SetDescription("");
1345 box_e = myTransformOperations->TranslateDXDYDZ
1346 (box_e, -theVertCylinderRadius, -theVertCylinderRadius, 0);
1347 box_e->GetLastFunction()->SetDescription("");
1349 aFunction = theShape->GetLastFunction();
1350 theDesc = aFunction->GetDescription();
1351 Handle(TColStd_HSequenceOfTransient) extremVertices =
1352 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1353 // Recover previous description to get rid of Propagate dump
1354 aFunction->SetDescription(theDesc);
1356 if (extremVertices.IsNull() || extremVertices->Length() == 0) {
1358 SetErrorCode("Vertices on chamfer not found");
1360 SetErrorCode("Vertices on fillet not found");
1364 theShapes.push_back(theShape);
1365 theShapes.push_back(box_e);
1366 if (extremVertices->Length() != 6) {
1367 // for (int i=1; i<=extremVertices->Length(); i++){
1368 // theShapes.push_back(Handle(GEOM_Object)::DownCast(extremVertices->Value(i)));
1370 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1371 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1372 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1373 SetErrorCode("Bad number of vertices on chamfer found");
1377 for (int i=1; i<=extremVertices->Length(); i++){
1378 Handle(GEOM_Object) aV = Handle(GEOM_Object)::DownCast(extremVertices->Value(i));
1379 aV->GetLastFunction()->SetDescription("");
1380 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aV->GetValue()));
1382 if (Abs(aP.X()) <= Precision::Confusion()) {
1383 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
1385 if (aP.Z()-ZX > Precision::Confusion()) {
1392 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
1394 if (aP.Z() - ZY > Precision::Confusion()) {
1405 if (LX.at(0) == PZX)
1408 if (LY.at(0) == PZY)
1411 P1 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP1));
1412 P2 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP2));
1413 P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
1414 P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4));
1416 Handle(GEOM_Object) Cote_1 = myBasicOperations->MakeLineTwoPnt(P1, vi1);
1417 if (Cote_1.IsNull()) {
1418 SetErrorCode("Impossible to build edge in thickness");
1421 Cote_1->GetLastFunction()->SetDescription("");
1423 Handle(GEOM_Object) Cote_2 = myBasicOperations->MakeLineTwoPnt(vi2, P3);
1424 if (Cote_2.IsNull()) {
1425 SetErrorCode("Impossible to build edge in thickness");
1428 Cote_2->GetLastFunction()->SetDescription("");
1430 // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
1431 // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
1432 // std::cerr << "Getting chamfer edge on main pipe" << std::endl;
1433 Handle(GEOM_Object) edge_chan_princ = myBlocksOperations->GetEdge(theShape, P1, P3);
1434 if (edge_chan_princ.IsNull()) {
1435 SetErrorCode("Impossible to find edge on main pipe");
1438 edge_chan_princ->GetLastFunction()->SetDescription("");
1440 Handle(GEOM_Object) edge_chan_inc = myBlocksOperations->GetEdge(theShape, P2, P4);
1441 if (edge_chan_inc.IsNull()) {
1442 SetErrorCode("Impossible to find edge on incident pipe");
1445 edge_chan_inc->GetLastFunction()->SetDescription("");
1447 std::list<Handle(GEOM_Object)> edgeList1;
1448 edgeList1.push_back(edge_chan_princ);
1449 edgeList1.push_back(Cote_1);
1450 edgeList1.push_back(arete_intersect_int);
1451 edgeList1.push_back(Cote_2);
1453 // std::cerr << "Creating wire 1" << std::endl;
1454 wire_t = myShapesOperations->MakeWire(edgeList1, 1e-7);
1455 if (wire_t.IsNull()) {
1456 SetErrorCode("Impossible to build wire");
1459 wire_t->GetLastFunction()->SetDescription("");
1461 // std::cerr << "Creating face 1" << std::endl;
1462 face_t = myShapesOperations->MakeFace(wire_t, false);
1463 if (face_t.IsNull()) {
1464 SetErrorCode("Impossible to build face");
1467 face_t->GetLastFunction()->SetDescription("");
1468 theShapes.push_back(face_t);
1470 gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(P2->GetValue()));
1471 gp_Pnt aP5 = BRep_Tool::Pnt(TopoDS::Vertex(vi1->GetValue()));
1472 double deltaZ = aP2.Z() - aP5.Z();
1473 // std::cerr << "Creating new point from vi1 with deltaZ = " << deltaZ << std::endl;
1474 Handle(GEOM_Object) P5bis = myTransformOperations->TranslateDXDYDZCopy(vi1, 0, 0, deltaZ);
1475 if (P5bis.IsNull()) {
1476 SetErrorCode("Impossible to translate vertex");
1479 P5bis->GetLastFunction()->SetDescription("");
1481 gp_Pnt aP4 = BRep_Tool::Pnt(TopoDS::Vertex(P4->GetValue()));
1482 gp_Pnt aP6 = BRep_Tool::Pnt(TopoDS::Vertex(vi2->GetValue()));
1483 deltaZ = aP4.Z() - aP6.Z();
1484 // std::cerr << "Creating new point from vi2 with deltaZ = " << deltaZ << std::endl;
1485 Handle(GEOM_Object) P6bis = myTransformOperations->TranslateDXDYDZCopy(vi2, 0, 0, deltaZ);
1486 if (P6bis.IsNull()) {
1487 SetErrorCode("Impossible to translate vertex");
1490 P6bis->GetLastFunction()->SetDescription("");
1492 // std::cerr << "Creating new line 1 from 2 previous points" << std::endl;
1493 Handle(GEOM_Object) Cote_3 = myBasicOperations->MakeLineTwoPnt(P5bis, P2);
1494 if (Cote_3.IsNull()) {
1495 SetErrorCode("Impossible to build edge in thickness");
1498 Cote_3->GetLastFunction()->SetDescription("");
1500 // std::cerr << "Creating new line 2 from 2 previous points" << std::endl;
1501 Handle(GEOM_Object) Cote_4 = myBasicOperations->MakeLineTwoPnt(P6bis, P4);
1502 if (Cote_4.IsNull()) {
1503 SetErrorCode("Impossible to build edge in thickness");
1506 Cote_4->GetLastFunction()->SetDescription("");
1508 // std::cerr << "Creating new line 3 from 2 previous points" << std::endl;
1509 Handle(GEOM_Object) Cote_5 = myBasicOperations->MakeLineTwoPnt(P5bis, P6bis);
1510 if (Cote_4.IsNull()) {
1511 SetErrorCode("Impossible to build edge in thickness");
1514 Cote_5->GetLastFunction()->SetDescription("");
1516 //std::list<Handle(GEOM_Object)> edgeList2;
1517 //edgeList2.push_back(edge_chan_inc);
1518 //edgeList2.push_back(Cote_3);
1519 //edgeList2.push_back(Cote_5);
1520 //edgeList2.push_back(Cote_4);
1521 // std::cerr << "Creating wire 2" << std::endl;
1522 //wire_t2 = myShapesOperations->MakeWire(edgeList2, 1e-7);
1523 //if (wire_t2.IsNull()) {
1524 // SetErrorCode("Impossible to build wire");
1527 //wire_t2->GetLastFunction()->SetDescription("");
1528 // std::cerr << "Creating face 2" << std::endl;
1529 //face_t2 = myShapesOperations->MakeFace(wire_t2, false);
1531 // Mantis issue 0021682
1532 face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - (theR2 + theW2));
1533 //face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - 2.0*theR2);
1534 if (face_t2.IsNull()) {
1535 SetErrorCode("Impossible to build face");
1538 face_t2->GetLastFunction()->SetDescription("");
1539 theShapes.push_back(face_t2);
1543 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1544 Handle(GEOM_Object) aVZ = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1545 Handle(GEOM_Object) aVXZ = myBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
1546 Handle(GEOM_Object) aPlnOZ = myBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
1547 Handle(GEOM_Object) aPlnOXZ = myBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
1548 aP0->GetLastFunction()->SetDescription("");
1549 aVZ->GetLastFunction()->SetDescription("");
1550 aVXZ->GetLastFunction()->SetDescription("");
1551 aPlnOZ->GetLastFunction()->SetDescription("");
1552 aPlnOXZ->GetLastFunction()->SetDescription("");
1553 theShapes.push_back(aPlnOZ);
1554 theShapes.push_back(aPlnOXZ);
1557 Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
1558 Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
1559 Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
1560 Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
1561 Handle(TColStd_HArray1OfInteger) theMaterials;
1563 partitionShapes->Append(theShape);
1564 theTools->Append(aPlnOZ);
1565 if (Abs(aR1Ext - aR2Ext) > Precision::Confusion())
1566 theTools->Append(aPlnOXZ);
1567 theTools->Append(face_t);
1569 theTools->Append(face_t2);
1571 Te3 = myBooleanOperations->MakePartition
1572 (partitionShapes, theTools, theKeepInside, theRemoveInside,
1573 TopAbs_SOLID, false, theMaterials, 0, false, Standard_False);
1575 SetErrorCode("Impossible to build partition of TShape");
1578 Te3->GetLastFunction()->SetDescription("");
1580 // Last verification: result should be a block
1581 std::list<GEOMImpl_IBlocksOperations::BCError> errList;
1582 if (!myBlocksOperations->CheckCompoundOfBlocks(Te3,errList)) {
1583 SetErrorCode("TShape is not a compound of block");
1587 // // BEGIN Compound of created shapes - Only for debug purpose
1588 // theShapes.clear();
1589 // theShapes.push_back(theShape);
1590 // theShapes.push_back(aPlnOZ);
1591 // if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
1592 // theShapes.push_back(aPlnOXZ);
1593 // theShapes.push_back(face_t);
1595 // theShapes.push_back(face_t2);
1597 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1598 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1599 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1600 // // END Compound of created shapes - Only for debug purpose
1602 TopoDS_Shape aShape = Te3->GetValue();
1603 theShape->GetLastFunction()->SetValue(aShape);
1605 catch (Standard_Failure) {
1606 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1607 SetErrorCode(aFail->GetMessageString());
1615 // Mirror and glue faces
1616 bool AdvancedEngine_IOperations::MakePipeTShapeMirrorAndGlue(Handle(GEOM_Object) theShape,
1617 double theR1, double theW1, double theL1,
1618 double theR2, double theW2, double theL2)
1623 double aSize = 2*(theL1 + theL2);
1624 double aR1Ext = theR1 + theW1;
1627 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1628 aP0->GetLastFunction()->SetDescription("");
1629 Handle(GEOM_Object) aVX = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
1630 Handle(GEOM_Object) aVY = myBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
1631 aVX->GetLastFunction()->SetDescription("");
1632 aVY->GetLastFunction()->SetDescription("");
1633 Handle(GEOM_Object) aPlane_OX = myBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
1634 Handle(GEOM_Object) aPlane_OY = myBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
1635 aPlane_OX->GetLastFunction()->SetDescription("");
1636 aPlane_OY->GetLastFunction()->SetDescription("");
1638 Handle(GEOM_Object) Te4 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
1640 SetErrorCode("Impossible to build mirror of quarter TShape");
1644 Handle(GEOM_Object) Te5 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
1646 SetErrorCode("Impossible to build mirror of half TShape");
1650 Handle(GEOM_Object) Te6 = myTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
1652 SetErrorCode("Impossible to build mirror of half TShape");
1656 std::list<Handle(GEOM_Object)> aShapesList;
1657 aShapesList.push_back(theShape);
1658 aShapesList.push_back(Te4);
1659 aShapesList.push_back(Te5);
1660 aShapesList.push_back(Te6);
1661 Handle(GEOM_Object) Te7 = myShapesOperations->MakeCompound(aShapesList);
1663 SetErrorCode("Impossible to build compound");
1667 // Copy source shape
1668 TopoDS_Shape aShapeCopy;
1669 TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
1670 TNaming_CopyShape::CopyTool(Te7->GetValue(), aMapTShapes, aShapeCopy);
1672 std::list<Handle(GEOM_Object)> Te7list( 1, Te7 );
1673 Handle(GEOM_Object) Te8 = myShapesOperations->MakeGlueFaces(Te7list, 1e-7, true);
1675 SetErrorCode("Impossible to glue faces of TShape");
1679 TopoDS_Shape aShape = Te8->GetValue();
1680 BRepCheck_Analyzer anAna (aShape, Standard_True);
1682 if (!anAna.IsValid()) {
1683 // Try to do gluing with the tolerance equal to maximal
1684 // tolerance of vertices of the source shape.
1685 Standard_Real aTolMax = -RealLast();
1687 for (TopExp_Explorer ExV (aShapeCopy, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1688 TopoDS_Vertex aVertex = TopoDS::Vertex(ExV.Current());
1689 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
1691 if (aTol > aTolMax) {
1697 Te7->GetLastFunction()->SetValue(aShapeCopy);
1698 Te8 = myShapesOperations->MakeGlueFaces(Te7list, aTolMax, true);
1701 SetErrorCode("Impossible to glue faces of TShape");
1705 aShape = Te8->GetValue();
1709 theShape->GetLastFunction()->SetValue(aShape);
1711 Te4->GetLastFunction()->SetDescription("");
1712 Te5->GetLastFunction()->SetDescription("");
1713 Te6->GetLastFunction()->SetDescription("");
1714 Te7->GetLastFunction()->SetDescription("");
1715 Te8->GetLastFunction()->SetDescription("");
1721 //=======================================================================
1722 //function : MakePipeTShapeThicknessReduction
1723 //purpose : Static method. Add thiskness reduction elements at the three
1724 // open ends of the T-Shape.
1725 //=======================================================================
1726 TopoDS_Shape AdvancedEngine_IOperations::MakePipeTShapeThicknessReduction
1727 (TopoDS_Shape theShape,
1728 double r1, double w1, double l1,
1729 double r2, double w2, double l2,
1730 double rL, double wL, double ltransL, double lthinL,
1731 double rR, double wR, double ltransR, double lthinR,
1732 double rI, double wI, double ltransI, double lthinI,
1733 bool fuseReductions)
1735 // Add thickness reduction elements
1736 // at the three extremities: Left, Right and Incident
1738 // ---------------------.
1740 // ---------------------. \
1741 // ^ \ '-----------------.
1743 // | '-----------------'
1745 // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--
1748 TopoDS_Shape aResult = theShape;
1749 double aTol = Precision::Confusion();
1751 gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
1753 // Left reduction (rL, wL, ltransL, lthinL)
1754 if (rL > aTol && wL > aTol && ltransL > aTol) {
1755 gp_Pnt aPLeft (-l1, 0, 0);
1756 gp_Ax2 anAxesLeft (aPLeft, -aVX, aVZ);
1757 TopoDS_Shape aReductionLeft = AdvancedEngine_IOperations::MakeThicknessReduction
1758 (anAxesLeft, r1, w1, rL, wL, ltransL, lthinL, fuseReductions);
1760 if (fuseReductions) {
1761 BRepAlgoAPI_Fuse fuseL (aResult, aReductionLeft);
1762 if (!fuseL.IsDone())
1763 StdFail_NotDone::Raise("Cannot fuse Te with left reduction");
1764 aResult = fuseL.Shape();
1771 B.Add(C, aReductionLeft);
1777 if (rR > aTol && wR > aTol && ltransR > aTol) {
1778 gp_Pnt aPRight (l1, 0, 0);
1779 gp_Ax2 anAxesRight (aPRight, aVX, aVZ);
1780 TopoDS_Shape aReductionRight = AdvancedEngine_IOperations::MakeThicknessReduction
1781 (anAxesRight, r1, w1, rR, wR, ltransR, lthinR, fuseReductions);
1783 if (fuseReductions) {
1784 BRepAlgoAPI_Fuse fuseR (aResult, aReductionRight);
1785 if (!fuseR.IsDone())
1786 StdFail_NotDone::Raise("Cannot fuse Te with right reduction");
1787 aResult = fuseR.Shape();
1794 B.Add(C, aReductionRight);
1799 // Incident reduction
1800 if (rI > aTol && wI > aTol && ltransI > aTol) {
1801 gp_Pnt aPInci (0, 0, l2);
1802 gp_Ax2 anAxesInci (aPInci, aVZ, aVX);
1803 TopoDS_Shape aReductionInci = AdvancedEngine_IOperations::MakeThicknessReduction
1804 (anAxesInci, r2, w2, rI, wI, ltransI, lthinI, fuseReductions);
1806 if (fuseReductions) {
1807 BRepAlgoAPI_Fuse fuseInci (aResult, aReductionInci);
1808 if (!fuseInci.IsDone())
1809 StdFail_NotDone::Raise("Cannot fuse Te with incident reduction");
1810 aResult = fuseInci.Shape();
1817 B.Add(C, aReductionInci);
1822 // Get rid of extra compounds
1823 TopTools_ListOfShape listShapeRes;
1824 GEOMUtils::AddSimpleShapes(aResult, listShapeRes);
1825 aResult = listShapeRes.First(); // useful for the case "fuseReductions == true"
1827 if (!fuseReductions && listShapeRes.Extent() > 1) {
1828 // Simplify T-Shape compound (get rid of sub-compounds) and glue duplicated faces
1833 TopTools_ListIteratorOfListOfShape itSub (listShapeRes);
1834 for (; itSub.More(); itSub.Next())
1835 B.Add(C, itSub.Value());
1838 aResult = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
1844 //=======================================================================
1845 //function : MakeThicknessReduction
1846 //purpose : Static method. Create one thickness reduction element.
1847 //=======================================================================
1848 TopoDS_Shape AdvancedEngine_IOperations::MakeThicknessReduction (gp_Ax2 theAxes,
1849 const double R, const double W,
1850 const double Rthin, const double Wthin,
1851 const double Ltrans, const double Lthin,
1854 double aTol = Precision::Confusion();
1855 if (Rthin < aTol || Wthin < aTol || Ltrans < aTol) {
1856 StdFail_NotDone::Raise("Cannot build thickness reduction: too small values");
1858 bool isThinPart = (Lthin > aTol);
1863 // ^ \ '-----------------.
1865 // | '-----------------'
1867 // --.--.--.--.--.--.--.--.--.--.--.--.--> theAxes.Direction()
1870 double RExt = R + W;
1871 double RthinExt = Rthin + Wthin;
1873 gp_Dir aNormal = theAxes.Direction();
1874 gp_Dir anXDir = theAxes.XDirection();
1875 gp_Pnt aPntCyl (theAxes.Location().XYZ() + aNormal.XYZ()*Ltrans);
1876 gp_Ax2 anAxesCyl (aPntCyl, aNormal, anXDir);
1878 // Build the transition part
1879 BRepPrimAPI_MakeCone ConeExt (theAxes, RExt, RthinExt, Ltrans);
1880 BRepPrimAPI_MakeCone ConeInt (theAxes, R, Rthin, Ltrans);
1883 if (!ConeExt.IsDone() || !ConeInt.IsDone())
1884 StdFail_NotDone::Raise("Cannot build cones of thickness reduction");
1885 BRepAlgoAPI_Cut cut1 (ConeExt.Shape(), ConeInt.Shape());
1887 StdFail_NotDone::Raise("Coudn't build transition part of thickness reduction");
1888 TopoDS_Shape aReduction = cut1.Shape();
1890 // Build the thin part, if required
1891 TopoDS_Shape aThinPart;
1893 BRepPrimAPI_MakeCylinder CExt (anAxesCyl, RthinExt, Lthin);
1894 BRepPrimAPI_MakeCylinder CInt (anAxesCyl, Rthin, Lthin);
1897 if (!CExt.IsDone() || !CInt.IsDone())
1898 StdFail_NotDone::Raise("Cannot build cylinders of thickness reduction");
1899 BRepAlgoAPI_Cut cut2 (CExt.Shape(), CInt.Shape());
1901 StdFail_NotDone::Raise("Coudn't build thin part of thickness reduction");
1902 aThinPart = cut2.Shape();
1908 BRepAlgoAPI_Fuse fuse1 (aReduction, aThinPart);
1909 if (!fuse1.IsDone())
1910 StdFail_NotDone::Raise("Cannot fuse parts of thickness reduction");
1911 aReduction = fuse1.Shape();
1915 // Partition the reduction on blocks
1916 gp_Ax3 anAxesPln1 (aPntCyl, theAxes.XDirection(), aNormal);
1917 gp_Ax3 anAxesPln2 (aPntCyl, theAxes.YDirection(), aNormal);
1918 gp_Pln aPln1 (anAxesPln1);
1919 gp_Pln aPln2 (anAxesPln2);
1920 double aSize = Ltrans + Lthin + R + Rthin + Wthin; // to guarantee enough size in all directions
1921 TopoDS_Shape aTool1 = BRepBuilderAPI_MakeFace(aPln1, -aSize, +aSize, -aSize, +aSize).Shape();
1922 TopoDS_Shape aTool2 = BRepBuilderAPI_MakeFace(aPln2, -aSize, +aSize, -aSize, +aSize).Shape();
1924 GEOMAlgo_Splitter PS;
1925 PS.AddArgument(aReduction);
1927 PS.AddArgument(aThinPart);
1930 PS.SetLimit(TopAbs_SOLID);
1933 aReduction = PS.Shape();
1939 //=============================================================================
1942 * \brief Create a T-shape object with specified caracteristics for the main and
1943 * the incident pipes (radius, width, half-length).
1944 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1945 * \param theR1 Internal radius of main pipe
1946 * \param theW1 Width of main pipe
1947 * \param theL1 Half-length of main pipe
1948 * \param theR2 Internal radius of incident pipe (R2 < R1)
1949 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1950 * \param theL2 Half-length of incident pipe
1951 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1952 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1954 //=============================================================================
1955 Handle(TColStd_HSequenceOfTransient)
1956 AdvancedEngine_IOperations::MakePipeTShape(double theR1, double theW1, double theL1,
1957 double theR2, double theW2, double theL2,
1958 double theRL, double theWL, double theLtransL, double theLthinL,
1959 double theRR, double theWR, double theLtransR, double theLthinR,
1960 double theRI, double theWI, double theLtransI, double theLthinI,
1963 MESSAGE("AdvancedEngine_IOperations::MakePipeTShape");
1966 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1968 //Add a new shape function with parameters
1969 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1970 if (aFunction.IsNull()) return NULL;
1972 //Check if the function is set correctly
1973 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
1975 AdvancedEngine_IPipeTShape aData (aFunction);
1983 aData.SetHexMesh(theHexMesh);
1985 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
1986 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
1987 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
1989 //Compute the resulting value
1992 if (!GetSolver()->ComputeFunction(aFunction)) {
1993 SetErrorCode("TShape driver failed");
1998 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2000 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2004 if (isTRL || isTRR || isTRI) {
2005 // Add thickness reduction elements
2006 // at the three extremities: Left, Right and Incident
2007 TopoDS_Shape aResShape =
2008 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2009 theRL, theWL, theLtransL, theLthinL,
2010 theRR, theWR, theLtransR, theLthinR,
2011 theRI, theWI, theLtransI, theLthinI,
2013 aFunction->SetValue(aResShape);
2016 catch (Standard_Failure) {
2017 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2018 SetErrorCode(aFail->GetMessageString());
2022 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2023 aSeq->Append(aShape);
2028 if (!MakeGroups(aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2029 0., 0., 0., aSeq, gp_Trsf()))
2033 // Get internal group.
2034 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2035 theRR, theLtransR, theRI, theLtransI,
2040 catch (Standard_Failure) {
2041 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2042 SetErrorCode(aFail->GetMessageString());
2046 //Make a Python command
2047 TCollection_AsciiString anEntry, aListRes("[");
2048 // Iterate over the sequence aSeq
2049 Standard_Integer aNbGroups = aSeq->Length();
2050 Standard_Integer i = 1;
2051 for (; i <= aNbGroups; i++) {
2052 Handle(Standard_Transient) anItem = aSeq->Value(i);
2053 if (anItem.IsNull()) continue;
2054 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2055 if (aGroup.IsNull()) continue;
2056 //Make a Python command
2057 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2058 aListRes += anEntry + ", ";
2060 aListRes.Trunc(aListRes.Length() - 2);
2062 GEOM::TPythonDump pd (aFunction);
2064 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2065 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2066 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2069 // thickness reduction
2071 pd << ", theRL=" << theRL << ", theWL=" << theWL
2072 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2074 pd << ", theRR=" << theRR << ", theWR=" << theWR
2075 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2077 pd << ", theRI=" << theRI << ", theWI=" << theWI
2078 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2087 //=============================================================================
2089 * MakePipeTShapeWithPosition
2090 * Create a T-shape object with specified caracteristics for the main and
2091 * the incident pipes (radius, width, half-length).
2092 * The extremities of the main pipe are located on junctions points P1 and P2.
2093 * The extremity of the incident pipe is located on junction point P3.
2094 * \param theR1 Internal radius of main pipe
2095 * \param theW1 Width of main pipe
2096 * \param theL1 Half-length of main pipe
2097 * \param theR2 Internal radius of incident pipe (R2 < R1)
2098 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2099 * \param theL2 Half-length of incident pipe
2100 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2101 * \param theP1 1st junction point of main pipe
2102 * \param theP2 2nd junction point of main pipe
2103 * \param theP3 Junction point of incident pipe
2104 * \return List of GEOM_Objects, containing the created shape and propagation groups..
2106 //=============================================================================
2107 Handle(TColStd_HSequenceOfTransient)
2108 AdvancedEngine_IOperations::MakePipeTShapeWithPosition
2109 (double theR1, double theW1, double theL1,
2110 double theR2, double theW2, double theL2,
2111 double theRL, double theWL, double theLtransL, double theLthinL,
2112 double theRR, double theWR, double theLtransR, double theLthinR,
2113 double theRI, double theWI, double theLtransI, double theLthinI,
2115 Handle(GEOM_Object) theP1,
2116 Handle(GEOM_Object) theP2,
2117 Handle(GEOM_Object) theP3)
2121 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2125 //Add a new shape function with parameters
2126 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
2127 if (aFunction.IsNull()) return NULL;
2129 //Check if the function is set correctly
2130 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2132 // Check new position
2133 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2137 AdvancedEngine_IPipeTShape aData(aFunction);
2145 aData.SetHexMesh(theHexMesh);
2147 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2148 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2149 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2151 //Compute the resulting value
2154 if (!GetSolver()->ComputeFunction(aFunction)) {
2155 SetErrorCode("TShape driver failed");
2160 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2162 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2166 if (isTRL || isTRR || isTRI) {
2167 // Add thickness reduction elements
2168 // at the three extremities: Left, Right and Incident
2169 TopoDS_Shape aResShape =
2170 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2171 theRL, theWL, theLtransL, theLthinL,
2172 theRR, theWR, theLtransR, theLthinR,
2173 theRI, theWI, theLtransI, theLthinI,
2175 aFunction->SetValue(aResShape);
2178 catch (Standard_Failure) {
2179 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2180 SetErrorCode(aFail->GetMessageString());
2184 TopoDS_Shape Te = aShape->GetValue();
2187 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2188 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
2189 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2190 aFunction->SetValue(aTrsf_Shape);
2192 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2193 aSeq->Append(aShape);
2198 if (!MakeGroups(aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2199 0., 0., 0., aSeq, aTrsf)) {
2204 // Get internal group.
2205 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2206 theRR, theLtransR, theRI, theLtransI,
2211 catch (Standard_Failure) {
2212 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2213 SetErrorCode(aFail->GetMessageString());
2217 //Make a Python command
2218 TCollection_AsciiString anEntry, aListRes("[");
2219 // Iterate over the sequence aSeq
2220 Standard_Integer aNbGroups = aSeq->Length();
2221 Standard_Integer i = 1;
2222 for (; i <= aNbGroups; i++) {
2223 Handle(Standard_Transient) anItem = aSeq->Value(i);
2224 if (anItem.IsNull()) continue;
2225 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2226 if (aGroup.IsNull()) continue;
2227 //Make a Python command
2228 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2229 aListRes += anEntry + ", ";
2231 aListRes.Trunc(aListRes.Length() - 2);
2233 GEOM::TPythonDump pd (aFunction);
2235 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2236 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2237 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2238 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3;
2240 // thickness reduction
2242 pd << ", theRL=" << theRL << ", theWL=" << theWL
2243 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2245 pd << ", theRR=" << theRR << ", theWR=" << theWR
2246 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2248 pd << ", theRI=" << theRI << ", theWI=" << theWI
2249 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2258 //=============================================================================
2260 * MakePipeTShapeChamfer
2261 * Create a T-shape object with specified caracteristics for the main and
2262 * the incident pipes (radius, width, half-length). A chamfer is created
2263 * on the junction of the pipes.
2264 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2265 * \param theR1 Internal radius of main pipe
2266 * \param theW1 Width of main pipe
2267 * \param theL1 Half-length of main pipe
2268 * \param theR2 Internal radius of incident pipe (R2 < R1)
2269 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2270 * \param theL2 Half-length of incident pipe
2271 * \param theH Height of chamfer.
2272 * \param theW Width of chamfer.
2273 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2274 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2276 //=============================================================================
2277 Handle(TColStd_HSequenceOfTransient)
2278 AdvancedEngine_IOperations::MakePipeTShapeChamfer
2279 (double theR1, double theW1, double theL1,
2280 double theR2, double theW2, double theL2,
2281 double theRL, double theWL, double theLtransL, double theLthinL,
2282 double theRR, double theWR, double theLtransR, double theLthinR,
2283 double theRI, double theWI, double theLtransI, double theLthinI,
2284 double theH, double theW,
2289 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2290 //Add a new shape function with parameters
2291 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2292 if (aFunction.IsNull()) return NULL;
2294 //Check if the function is set correctly
2295 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2297 AdvancedEngine_IPipeTShape aData(aFunction);
2307 aData.SetHexMesh(theHexMesh);
2309 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2310 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2311 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2313 //Compute the resulting value
2316 if (!GetSolver()->ComputeFunction(aFunction)) {
2317 SetErrorCode("TShape driver failed");
2321 catch (Standard_Failure) {
2322 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2323 SetErrorCode(aFail->GetMessageString());
2328 TopoDS_Shape aShapeShape = aShape->GetValue();
2329 TopTools_IndexedMapOfShape anEdgesIndices;
2330 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2331 // Common edges on external cylinders
2332 Handle(GEOM_Object) box_e;
2334 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2337 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2339 box_e->GetLastFunction()->SetDescription("");
2340 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2341 box_e->GetLastFunction()->SetDescription("");
2343 Handle(TColStd_HSequenceOfInteger) edges_e =
2344 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2345 box_e->GetLastFunction()->SetDescription("");
2347 if (edges_e.IsNull() || edges_e->Length() == 0) {
2348 SetErrorCode("External edges not found");
2351 int nbEdgesInChamfer = 0;
2352 std::list<int> theEdges;
2353 for (int i=1; i<=edges_e->Length();i++) {
2354 int edgeID = edges_e->Value(i);
2355 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2356 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2360 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2361 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2362 nbEdgesInChamfer ++;
2363 theEdges.push_back(edgeID);
2367 if (theHexMesh && nbEdgesInChamfer == 1)
2370 Handle(GEOM_Object) aChamfer;
2372 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2374 catch (Standard_Failure) {
2375 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2376 SetErrorCode(aFail->GetMessageString());
2379 if (aChamfer.IsNull()) {
2380 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2383 aChamfer->GetLastFunction()->SetDescription("");
2385 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2386 aFunction->SetValue(aChamferShape);
2390 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2392 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2396 // Add thickness reduction elements
2397 // at the three extremities: Left, Right and Incident
2400 if (isTRL || isTRR || isTRI) {
2401 TopoDS_Shape aResShape =
2402 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2403 theRL, theWL, theLtransL, theLthinL,
2404 theRR, theWR, theLtransR, theLthinR,
2405 theRI, theWI, theLtransI, theLthinI,
2407 aFunction->SetValue(aResShape);
2410 catch (Standard_Failure) {
2411 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2412 SetErrorCode(aFail->GetMessageString());
2416 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2417 aSeq->Append(aShape);
2422 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2423 theH, theW, 0., aSeq, gp_Trsf()))
2427 // Get internal group.
2428 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2429 theRR, theLtransR, theRI, theLtransI,
2434 catch (Standard_Failure) {
2435 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2436 SetErrorCode(aFail->GetMessageString());
2440 //Make a Python command
2441 TCollection_AsciiString anEntry, aListRes("[");
2442 // Iterate over the sequence aSeq
2443 Standard_Integer aNbGroups = aSeq->Length();
2444 Standard_Integer i = 1;
2445 for (; i <= aNbGroups; i++) {
2446 Handle(Standard_Transient) anItem = aSeq->Value(i);
2447 if (anItem.IsNull()) continue;
2448 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2449 if (aGroup.IsNull()) continue;
2450 //Make a Python command
2451 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2452 aListRes += anEntry + ", ";
2454 aListRes.Trunc(aListRes.Length() - 2);
2456 GEOM::TPythonDump pd (aFunction);
2458 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2459 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2460 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2461 << theH << ", " << theW << ", " << theHexMesh;
2463 // thickness reduction
2465 pd << ", theRL=" << theRL << ", theWL=" << theWL
2466 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2468 pd << ", theRR=" << theRR << ", theWR=" << theWR
2469 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2471 pd << ", theRI=" << theRI << ", theWI=" << theWI
2472 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2481 //=============================================================================
2483 * MakePipeTShapeChamferWithPosition
2484 * Create a T-shape object with specified caracteristics for the main and
2485 * the incident pipes (radius, width, half-length). A chamfer is created
2486 * on the junction of the pipes.
2487 * The extremities of the main pipe are located on junctions points P1 and P2.
2488 * The extremity of the incident pipe is located on junction point P3.
2489 * \param theR1 Internal radius of main pipe
2490 * \param theW1 Width of main pipe
2491 * \param theL1 Half-length of main pipe
2492 * \param theR2 Internal radius of incident pipe (R2 < R1)
2493 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2494 * \param theL2 Half-length of incident pipe
2495 * \param theH Height of chamfer.
2496 * \param theW Width of chamfer.
2497 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2498 * \param theP1 1st junction point of main pipe
2499 * \param theP2 2nd junction point of main pipe
2500 * \param theP3 Junction point of incident pipe
2501 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2503 //=============================================================================
2504 Handle(TColStd_HSequenceOfTransient)
2505 AdvancedEngine_IOperations::MakePipeTShapeChamferWithPosition
2506 (double theR1, double theW1, double theL1,
2507 double theR2, double theW2, double theL2,
2508 double theRL, double theWL, double theLtransL, double theLthinL,
2509 double theRR, double theWR, double theLtransR, double theLthinR,
2510 double theRI, double theWI, double theLtransI, double theLthinI,
2511 double theH, double theW,
2513 Handle(GEOM_Object) theP1,
2514 Handle(GEOM_Object) theP2,
2515 Handle(GEOM_Object) theP3)
2519 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2520 //Add a new shape function with parameters
2521 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2522 if (aFunction.IsNull()) return NULL;
2524 //Check if the function is set correctly
2525 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2527 // Check new position
2528 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2532 AdvancedEngine_IPipeTShape aData(aFunction);
2542 aData.SetHexMesh(theHexMesh);
2544 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2545 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2546 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2548 //Compute the resulting value
2551 if (!GetSolver()->ComputeFunction(aFunction)) {
2552 SetErrorCode("TShape driver failed");
2556 catch (Standard_Failure) {
2557 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2558 SetErrorCode(aFail->GetMessageString());
2563 TopoDS_Shape aShapeShape = aShape->GetValue();
2564 TopTools_IndexedMapOfShape anEdgesIndices;
2565 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2566 // Common edges on external cylinders
2567 Handle(GEOM_Object) box_e;
2569 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2572 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2574 box_e->GetLastFunction()->SetDescription("");
2575 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2576 box_e->GetLastFunction()->SetDescription("");
2578 Handle(TColStd_HSequenceOfInteger) edges_e =
2579 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2580 box_e->GetLastFunction()->SetDescription("");
2582 if (edges_e.IsNull() || edges_e->Length() == 0) {
2583 SetErrorCode("External edges not found");
2586 int nbEdgesInChamfer = 0;
2587 std::list<int> theEdges;
2588 for (int i=1; i<=edges_e->Length();i++) {
2589 int edgeID = edges_e->Value(i);
2590 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2591 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2593 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2594 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2595 nbEdgesInChamfer ++;
2596 theEdges.push_back(edgeID);
2600 if (theHexMesh && nbEdgesInChamfer == 1)
2603 Handle(GEOM_Object) aChamfer;
2605 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2607 catch (Standard_Failure) {
2608 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2609 SetErrorCode(aFail->GetMessageString());
2612 if (aChamfer.IsNull()) {
2613 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2616 aChamfer->GetLastFunction()->SetDescription("");
2618 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2619 aFunction->SetValue(aChamferShape);
2623 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2625 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2629 // Add thickness reduction elements
2630 // at the three extremities: Left, Right and Incident
2633 if (isTRL || isTRR || isTRI) {
2634 TopoDS_Shape aResShape =
2635 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2636 theRL, theWL, theLtransL, theLthinL,
2637 theRR, theWR, theLtransR, theLthinR,
2638 theRI, theWI, theLtransI, theLthinI,
2640 aFunction->SetValue(aResShape);
2643 catch (Standard_Failure) {
2644 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2645 SetErrorCode(aFail->GetMessageString());
2650 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2651 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
2652 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2653 aFunction->SetValue(aTrsf_Shape);
2655 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2656 aSeq->Append(aShape);
2661 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2662 theH, theW, 0., aSeq, aTrsf))
2666 // Get internal group.
2667 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2668 theRR, theLtransR, theRI, theLtransI,
2673 catch (Standard_Failure) {
2674 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2675 SetErrorCode(aFail->GetMessageString());
2679 //Make a Python command
2680 TCollection_AsciiString anEntry, aListRes("[");
2681 // Iterate over the sequence aSeq
2682 Standard_Integer aNbGroups = aSeq->Length();
2683 Standard_Integer i = 1;
2684 for (; i <= aNbGroups; i++) {
2685 Handle(Standard_Transient) anItem = aSeq->Value(i);
2686 if (anItem.IsNull()) continue;
2687 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2688 if (aGroup.IsNull()) continue;
2689 //Make a Python command
2690 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2691 aListRes += anEntry + ", ";
2693 aListRes.Trunc(aListRes.Length() - 2);
2695 GEOM::TPythonDump pd (aFunction);
2697 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2698 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2699 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2700 << theH << ", " << theW << ", " << theHexMesh << ", "
2701 << theP1 << ", " << theP2 << ", " << theP3;
2703 // thickness reduction
2705 pd << ", theRL=" << theRL << ", theWL=" << theWL
2706 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2708 pd << ", theRR=" << theRR << ", theWR=" << theWR
2709 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2711 pd << ", theRI=" << theRI << ", theWI=" << theWI
2712 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2721 //=============================================================================
2723 * MakePipeTShapeFillet
2724 * Create a T-shape object with specified caracteristics for the main and
2725 * the incident pipes (radius, width, half-length). A fillet is created
2726 * on the junction of the pipes.
2727 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2728 * \param theR1 Internal radius of main pipe
2729 * \param theW1 Width of main pipe
2730 * \param theL1 Half-length of main pipe
2731 * \param theR2 Internal radius of incident pipe (R2 < R1)
2732 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2733 * \param theL2 Half-length of incident pipe
2734 * \param theRF Radius of curvature of fillet.
2735 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2736 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2738 //=============================================================================
2739 Handle(TColStd_HSequenceOfTransient)
2740 AdvancedEngine_IOperations::MakePipeTShapeFillet
2741 (double theR1, double theW1, double theL1,
2742 double theR2, double theW2, double theL2,
2743 double theRL, double theWL, double theLtransL, double theLthinL,
2744 double theRR, double theWR, double theLtransR, double theLthinR,
2745 double theRI, double theWI, double theLtransI, double theLthinI,
2746 double theRF, bool theHexMesh)
2750 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2751 //Add a new shape function with parameters
2752 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2753 if (aFunction.IsNull()) return NULL;
2755 //Check if the function is set correctly
2756 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2758 AdvancedEngine_IPipeTShape aData(aFunction);
2767 aData.SetHexMesh(theHexMesh);
2769 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2770 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2771 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2773 //Compute the resulting value
2776 if (!GetSolver()->ComputeFunction(aFunction)) {
2777 SetErrorCode("TShape driver failed");
2781 catch (Standard_Failure) {
2782 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2783 SetErrorCode(aFail->GetMessageString());
2788 TopoDS_Shape aShapeShape = aShape->GetValue();
2789 TopTools_IndexedMapOfShape anEdgesIndices;
2790 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2791 // Common edges on external cylinders
2792 Handle(GEOM_Object) box_e;
2794 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2797 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2799 box_e->GetLastFunction()->SetDescription("");
2800 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2801 box_e->GetLastFunction()->SetDescription("");
2803 Handle(TColStd_HSequenceOfInteger) edges_e =
2804 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2805 box_e->GetLastFunction()->SetDescription("");
2807 if (edges_e.IsNull() || edges_e->Length() == 0) {
2808 SetErrorCode("External edges not found");
2811 int nbEdgesInFillet = 0;
2812 std::list<int> theEdges;
2813 for (int i=1; i<=edges_e->Length();i++) {
2814 int edgeID = edges_e->Value(i);
2815 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2816 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2818 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2819 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2821 theEdges.push_back(edgeID);
2825 if (theHexMesh && nbEdgesInFillet == 1)
2829 Handle(GEOM_Object) aFillet;
2831 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2833 catch (Standard_Failure) {
2834 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2835 SetErrorCode(aFail->GetMessageString());
2838 if (aFillet.IsNull()) {
2839 //SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
2840 SetErrorCode(myLocalOperations->GetErrorCode());
2843 aFillet->GetLastFunction()->SetDescription("");
2845 TopoDS_Shape aFilletShape = aFillet->GetValue();
2846 aFunction->SetValue(aFilletShape);
2849 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (1)
2850 // the following block, when enabled, leads to partitioning problems
2852 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (1)
2853 // BEGIN: Limit tolerances (debug)
2854 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
2855 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
2856 aShape->GetLastFunction()->SetValue(aCorr1Shape);
2857 aCorr1->GetLastFunction()->SetDescription("");
2858 // END: Limit tolerances (debug)
2859 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (2)
2861 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (2)
2864 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2866 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2870 // Add thickness reduction elements
2871 // at the three extremities: Left, Right and Incident
2874 if (isTRL || isTRR || isTRI) {
2875 TopoDS_Shape aResShape =
2876 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2877 theRL, theWL, theLtransL, theLthinL,
2878 theRR, theWR, theLtransR, theLthinR,
2879 theRI, theWI, theLtransI, theLthinI,
2881 aFunction->SetValue(aResShape);
2884 catch (Standard_Failure) {
2885 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2886 SetErrorCode(aFail->GetMessageString());
2890 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2891 aSeq->Append(aShape);
2896 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
2897 0., 0., theRF, aSeq, gp_Trsf()))
2901 // Get internal group.
2902 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2903 theRR, theLtransR, theRI, theLtransI,
2908 catch (Standard_Failure) {
2909 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2910 SetErrorCode(aFail->GetMessageString());
2914 //Make a Python command
2915 TCollection_AsciiString anEntry, aListRes("[");
2916 // Iterate over the sequence aSeq
2917 Standard_Integer aNbGroups = aSeq->Length();
2918 Standard_Integer i = 1;
2919 for (; i <= aNbGroups; i++) {
2920 Handle(Standard_Transient) anItem = aSeq->Value(i);
2921 if (anItem.IsNull()) continue;
2922 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2923 if (aGroup.IsNull()) continue;
2924 //Make a Python command
2925 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2926 aListRes += anEntry + ", ";
2928 aListRes.Trunc(aListRes.Length() - 2);
2930 GEOM::TPythonDump pd (aFunction);
2932 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
2933 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2934 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2935 << theRF << ", " << theHexMesh;
2937 // thickness reduction
2939 pd << ", theRL=" << theRL << ", theWL=" << theWL
2940 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2942 pd << ", theRR=" << theRR << ", theWR=" << theWR
2943 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2945 pd << ", theRI=" << theRI << ", theWI=" << theWI
2946 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2955 //=============================================================================
2957 * MakePipeTShapeFilletWithPosition
2958 * \brief Create a T-shape object with specified caracteristics for the main and
2959 * the incident pipes (radius, width, half-length). A fillet is created
2960 * on the junction of the pipes.
2961 * The extremities of the main pipe are located on junctions points P1 and P2.
2962 * The extremity of the incident pipe is located on junction point P3.
2963 * \param theR1 Internal radius of main pipe
2964 * \param theW1 Width of main pipe
2965 * \param theL1 Half-length of main pipe
2966 * \param theR2 Internal radius of incident pipe (R2 < R1)
2967 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2968 * \param theL2 Half-length of incident pipe
2969 * \param theRF Radius of curvature of fillet
2970 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2971 * \param theP1 1st junction point of main pipe
2972 * \param theP2 2nd junction point of main pipe
2973 * \param theP3 Junction point of incident pipe
2974 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2976 //=============================================================================
2977 Handle(TColStd_HSequenceOfTransient)
2978 AdvancedEngine_IOperations::MakePipeTShapeFilletWithPosition
2979 (double theR1, double theW1, double theL1,
2980 double theR2, double theW2, double theL2,
2981 double theRL, double theWL, double theLtransL, double theLthinL,
2982 double theRR, double theWR, double theLtransR, double theLthinR,
2983 double theRI, double theWI, double theLtransI, double theLthinI,
2984 double theRF, bool theHexMesh,
2985 Handle(GEOM_Object) theP1,
2986 Handle(GEOM_Object) theP2,
2987 Handle(GEOM_Object) theP3)
2991 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2992 //Add a new shape function with parameters
2993 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2994 if (aFunction.IsNull()) return NULL;
2996 //Check if the function is set correctly
2997 if (aFunction->GetDriverGUID() != AdvancedEngine_PipeTShapeDriver::GetID()) return NULL;
2999 // Check new position
3000 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
3004 AdvancedEngine_IPipeTShape aData(aFunction);
3013 aData.SetHexMesh(theHexMesh);
3015 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
3016 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
3017 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
3019 //Compute the resulting value
3022 if (!GetSolver()->ComputeFunction(aFunction)) {
3023 SetErrorCode("TShape driver failed");
3027 catch (Standard_Failure) {
3028 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3029 SetErrorCode(aFail->GetMessageString());
3034 TopoDS_Shape aShapeShape = aShape->GetValue();
3035 TopTools_IndexedMapOfShape anEdgesIndices;
3036 TopExp::MapShapes(aShapeShape, anEdgesIndices);
3037 // Common edges on external cylinders
3038 Handle(GEOM_Object) box_e;
3040 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
3043 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
3045 box_e->GetLastFunction()->SetDescription("");
3046 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
3047 box_e->GetLastFunction()->SetDescription("");
3049 Handle(TColStd_HSequenceOfInteger) edges_e =
3050 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
3051 box_e->GetLastFunction()->SetDescription("");
3053 if (edges_e.IsNull() || edges_e->Length() == 0) {
3054 SetErrorCode("External edges not found");
3057 int nbEdgesInFillet = 0;
3058 std::list<int> theEdges;
3059 for (int i=1; i<=edges_e->Length();i++) {
3060 int edgeID = edges_e->Value(i);
3061 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
3062 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
3064 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
3065 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
3067 theEdges.push_back(edgeID);
3071 if (theHexMesh && nbEdgesInFillet == 1)
3075 Handle(GEOM_Object) aFillet;
3077 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
3079 catch (Standard_Failure) {
3080 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3081 SetErrorCode(aFail->GetMessageString());
3084 if (aFillet.IsNull()) {
3085 SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
3088 aFillet->GetLastFunction()->SetDescription("");
3090 TopoDS_Shape aFilletShape = aFillet->GetValue();
3091 aFunction->SetValue(aFilletShape);
3094 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (3)
3095 // the following block, when enabled, leads to partitioning problems
3097 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (3)
3098 // BEGIN: Limit tolerances (debug)
3099 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
3100 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
3101 aShape->GetLastFunction()->SetValue(aCorr1Shape);
3102 aCorr1->GetLastFunction()->SetDescription("");
3103 // END: Limit tolerances (debug)
3104 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (4)
3106 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (4)
3109 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
3111 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
3115 // Add thickness reduction elements
3116 // at the three extremities: Left, Right and Incident
3119 if (isTRL || isTRR || isTRI) {
3120 TopoDS_Shape aResShape =
3121 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
3122 theRL, theWL, theLtransL, theLthinL,
3123 theRR, theWR, theLtransR, theLthinR,
3124 theRI, theWI, theLtransI, theLthinI,
3126 aFunction->SetValue(aResShape);
3129 catch (Standard_Failure) {
3130 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3131 SetErrorCode(aFail->GetMessageString());
3136 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
3137 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
3138 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
3139 aFunction->SetValue(aTrsf_Shape);
3141 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
3142 aSeq->Append(aShape);
3147 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
3148 0., 0., theRF, aSeq, aTrsf))
3152 // Get internal group.
3153 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
3154 theRR, theLtransR, theRI, theLtransI,
3159 catch (Standard_Failure) {
3160 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3161 SetErrorCode(aFail->GetMessageString());
3165 //Make a Python command
3166 TCollection_AsciiString anEntry, aListRes("[");
3167 // Iterate over the sequence aSeq
3168 Standard_Integer aNbGroups = aSeq->Length();
3169 Standard_Integer i = 1;
3170 for (; i <= aNbGroups; i++) {
3171 Handle(Standard_Transient) anItem = aSeq->Value(i);
3172 if (anItem.IsNull()) continue;
3173 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
3174 if (aGroup.IsNull()) continue;
3175 //Make a Python command
3176 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
3177 aListRes += anEntry + ", ";
3179 aListRes.Trunc(aListRes.Length() - 2);
3181 GEOM::TPythonDump pd (aFunction);
3183 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
3184 << theR1 << ", " << theW1 << ", " << theL1 << ", "
3185 << theR2 << ", " << theW2 << ", " << theL2 << ", "
3186 << theRF << ", " << theHexMesh << ", "
3187 << theP1 << ", " << theP2 << ", " << theP3;
3189 // thickness reduction
3191 pd << ", theRL=" << theRL << ", theWL=" << theWL
3192 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
3194 pd << ", theRR=" << theRR << ", theWR=" << theWR
3195 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
3197 pd << ", theRI=" << theRI << ", theWI=" << theWI
3198 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
3207 //=============================================================================
3209 * This function allows to create a disk already divided into blocks. It can be
3210 * used to create divided pipes for later meshing in hexaedra.
3211 * \param theR Radius of the disk
3212 * \param theRatio Relative size of the central square diagonal against the disk diameter
3213 * \param theOrientation Plane on which the disk will be built
3214 * \param thePattern The division pattern of the disk (hexagon or square in the center)
3215 * \return New GEOM_Object, containing the created shape.
3217 //=============================================================================
3218 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDisk (double theR, double theRatio,
3219 int theOrientation, int thePattern)
3223 if (theOrientation != 1 &&
3224 theOrientation != 2 &&
3225 theOrientation != 3)
3227 SetErrorCode("theOrientation must be 1(=OXY), 2(=OYZ) or 3(=OZX)");
3231 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3233 //Add a new shape function with parameters
3234 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_RATIO);
3235 if (aFunction.IsNull()) return NULL;
3237 //Check if the function is set correctly
3238 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3240 AdvancedEngine_IDividedDisk aData (aFunction);
3243 aData.SetRatio(theRatio);
3244 aData.SetOrientation(theOrientation);
3245 aData.SetType(thePattern);
3247 //Compute the resulting value
3250 if (!GetSolver()->ComputeFunction(aFunction)) {
3251 SetErrorCode("DividedDisk driver failed");
3255 catch (Standard_Failure) {
3256 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3257 SetErrorCode(aFail->GetMessageString());
3261 std::string aPatternStr;
3266 aPatternStr = "GEOM.SQUARE";
3269 aPatternStr = "GEOM.HEXAGON";
3273 //Make a Python command
3274 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDisk(" << theR << ", " << theOrientation << ", " << aPatternStr.c_str() << ")";
3281 //=============================================================================
3283 * This function allows to create a disk already divided into blocks. It can be
3284 * used to create divided pipes for later meshing in hexaedra.
3285 * \param theR Radius of the disk
3286 * \param theRatio Relative size of the central square diagonal against the disk diameter
3287 * \return New GEOM_Object, containing the created shape.
3289 //=============================================================================
3290 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedDiskPntVecR (Handle(GEOM_Object) thePnt,
3291 Handle(GEOM_Object) theVec,
3299 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3301 //Add a new shape function with parameters
3302 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_DividedDiskDriver::GetID(), DIVIDEDDISK_R_VECTOR_PNT);
3303 if (aFunction.IsNull()) return NULL;
3305 //Check if the function is set correctly
3306 if (aFunction->GetDriverGUID() != AdvancedEngine_DividedDiskDriver::GetID()) return NULL;
3308 AdvancedEngine_IDividedDisk aData (aFunction);
3310 Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
3311 Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
3313 if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
3315 aData.SetCenter(aRefPnt);
3316 aData.SetVector(aRefVec);
3319 aData.SetRatio(theRatio);
3320 aData.SetType(thePattern);
3322 //Compute the resulting value
3325 if (!GetSolver()->ComputeFunction(aFunction)) {
3326 SetErrorCode("DividedDisk driver failed");
3330 catch (Standard_Failure) {
3331 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3332 SetErrorCode(aFail->GetMessageString());
3336 std::string aPatternStr;
3341 aPatternStr = "GEOM.SQUARE";
3344 aPatternStr = "GEOM.HEXAGON";
3349 //Make a Python command
3350 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDiskPntVecR(" << thePnt << ", " << theVec << ", " << theR << ", " << aPatternStr.c_str() << ")";
3357 //=============================================================================
3359 * Builds a cylinder prepared for hexa meshes
3360 * \param theR Radius of the cylinder
3361 * \param theH Height of the cylinder
3362 * \return New GEOM_Object, containing the created shape.
3364 //=============================================================================
3365 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeDividedCylinder (double theR,
3372 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDCYLINDER);
3374 Handle(GEOM_Object) aBaseShape = MakeDividedDisk(theR, 67.0, 1, thePattern);
3375 aBaseShape->GetLastFunction()->SetDescription(""); // Erase dump of MakeDividedDisk
3377 aShape = my3DPrimOperations->MakePrismDXDYDZ(aBaseShape,0.0,0.0,theH, -1.0);
3379 Handle(GEOM_Function) aFunction = aShape->GetLastFunction();
3380 aFunction->SetDescription(""); // Erase dump of MakePrismDXDYDZ
3381 aShape->SetType(GEOM_DIVIDEDCYLINDER);
3383 std::string aPatternStr;
3388 aPatternStr = "GEOM.SQUARE";
3391 aPatternStr = "GEOM.HEXAGON";
3395 //Make a Python command
3396 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedCylinder(" << theR << ", " << theH << ", " << aPatternStr.c_str() << ")";
3402 //=============================================================================
3404 * Create a smoothing surface from a set of points
3405 * \param thelPoints list of points or compounds of points
3406 * \param theNbMax maximum number of Bezier pieces in the resulting surface.
3407 * \param theDegMax maximum degree of the resulting BSpline surface
3408 * \param theDMax specifies maximum value of the GeomPlate_PlateG0Criterion criterion.
3409 * \return New GEOM_Object, containing the created shape.
3411 //=============================================================================
3412 Handle(GEOM_Object) AdvancedEngine_IOperations::MakeSmoothingSurface (std::list<Handle(GEOM_Object)> thelPoints,
3420 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_SMOOTHINGSURFACE);
3422 //Add a new shape function with parameters
3423 Handle(GEOM_Function) aFunction = aShape->AddFunction(AdvancedEngine_SmoothingSurfaceDriver::GetID(), SMOOTHINGSURFACE_LPOINTS);
3424 if (aFunction.IsNull()) return NULL;
3426 //Check if the function is set correctly
3427 if (aFunction->GetDriverGUID() != AdvancedEngine_SmoothingSurfaceDriver::GetID()) return NULL;
3429 AdvancedEngine_ISmoothingSurface aData (aFunction);
3431 int aLen = thelPoints.size();
3432 aData.SetLength(aLen);
3434 std::list<Handle(GEOM_Object)>::iterator it = thelPoints.begin();
3435 for (; it != thelPoints.end(); it++, ind++) {
3436 Handle(GEOM_Function) aRefObj = (*it)->GetLastFunction();
3437 if (aRefObj.IsNull()) {
3438 SetErrorCode("NULL point or compound for bSplineFaceShape");
3441 aData.SetPntOrComp(ind, aRefObj);
3444 aData.SetNbMax(theNbMax);
3445 aData.SetDegMax(theDegMax);
3446 aData.SetDMax(theDMax);
3448 //Compute the resulting value
3451 if (!GetSolver()->ComputeFunction(aFunction)) {
3452 SetErrorCode("SmoothingSurface driver failed");
3456 catch (Standard_Failure) {
3457 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3458 SetErrorCode(aFail->GetMessageString());
3462 //Make a Python command
3463 GEOM::TPythonDump pd (aFunction);
3464 pd << aShape << " = geompy.MakeSmoothingSurface([";
3465 it = thelPoints.begin();
3467 while (it != thelPoints.end()) {
3468 pd << ", " << (*it++);
3472 << theDegMax << ", "