| 1 | // Created by: Peter KURNEV |
| 2 | // Copyright (c) 2010-2014 OPEN CASCADE SAS |
| 3 | // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE |
| 4 | // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT, |
| 5 | // EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS |
| 6 | // |
| 7 | // This file is part of Open CASCADE Technology software library. |
| 8 | // |
| 9 | // This library is free software; you can redistribute it and/or modify it under |
| 10 | // the terms of the GNU Lesser General Public License version 2.1 as published |
| 11 | // by the Free Software Foundation, with special exception defined in the file |
| 12 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
| 13 | // distribution for complete text of the license and disclaimer of any warranty. |
| 14 | // |
| 15 | // Alternatively, this file may be used under the terms of Open CASCADE |
| 16 | // commercial license or contractual agreement. |
| 17 | |
| 18 | #include <BOPAlgo_PaveFiller.ixx> |
| 19 | |
| 20 | #include <NCollection_IncAllocator.hxx> |
| 21 | |
| 22 | #include <TopoDS_Vertex.hxx> |
| 23 | #include <TopoDS_Edge.hxx> |
| 24 | #include <TopoDS_Face.hxx> |
| 25 | |
| 26 | #include <BRepBndLib.hxx> |
| 27 | |
| 28 | #include <BRep_Tool.hxx> |
| 29 | #include <BRep_Builder.hxx> |
| 30 | |
| 31 | #include <TopExp.hxx> |
| 32 | |
| 33 | #include <Geom_Curve.hxx> |
| 34 | #include <Geom_Surface.hxx> |
| 35 | #include <Geom2d_Curve.hxx> |
| 36 | |
| 37 | #include <BOPTools_AlgoTools.hxx> |
| 38 | #include <BOPTools_AlgoTools2D.hxx> |
| 39 | |
| 40 | #include <BOPDS_VectorOfListOfPaveBlock.hxx> |
| 41 | #include <BOPDS_ListOfPaveBlock.hxx> |
| 42 | #include <BOPDS_PaveBlock.hxx> |
| 43 | #include <BOPDS_CommonBlock.hxx> |
| 44 | #include <BOPDS_Pave.hxx> |
| 45 | #include <BOPDS_ShapeInfo.hxx> |
| 46 | #include <BOPDS_MapOfPaveBlock.hxx> |
| 47 | #include <BOPDS_VectorOfInterfFF.hxx> |
| 48 | #include <BOPDS_Interf.hxx> |
| 49 | #include <BOPDS_VectorOfCurve.hxx> |
| 50 | #include <BOPDS_VectorOfFaceInfo.hxx> |
| 51 | #include <BOPDS_FaceInfo.hxx> |
| 52 | #include <BOPDS_MapOfPaveBlock.hxx> |
| 53 | #include <BOPDS_Curve.hxx> |
| 54 | |
| 55 | static void UpdateVertices(const TopoDS_Edge& aE, |
| 56 | const TopoDS_Face& aF); |
| 57 | |
| 58 | //======================================================================= |
| 59 | // function: MakeSplitEdges |
| 60 | // purpose: |
| 61 | //======================================================================= |
| 62 | void BOPAlgo_PaveFiller::MakeSplitEdges() |
| 63 | { |
| 64 | Standard_Integer aNbPBP; |
| 65 | // |
| 66 | myErrorStatus=0; |
| 67 | // |
| 68 | BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool(); |
| 69 | aNbPBP=aPBP.Extent(); |
| 70 | if(!aNbPBP) { |
| 71 | return; |
| 72 | } |
| 73 | // |
| 74 | Standard_Boolean bCB, bV1, bV2; |
| 75 | Standard_Integer i, nE, nV1, nV2, nSp, aNbPB; |
| 76 | Standard_Real aT1, aT2; |
| 77 | Handle(NCollection_IncAllocator) aAllocator; |
| 78 | BOPDS_ListIteratorOfListOfPaveBlock aItPB, aItPBCB; |
| 79 | Handle(BOPDS_PaveBlock) aPB, aPBx; |
| 80 | //-----------------------------------------------------scope f |
| 81 | // |
| 82 | aAllocator=new NCollection_IncAllocator(); |
| 83 | // |
| 84 | BOPDS_MapOfPaveBlock aMPB(100,aAllocator); |
| 85 | // |
| 86 | for (i=0; i<aNbPBP; ++i) { |
| 87 | BOPDS_ListOfPaveBlock& aLPB=aPBP(i); |
| 88 | // |
| 89 | aNbPB=aLPB.Extent(); |
| 90 | //DEBf |
| 91 | if (aNbPB) { |
| 92 | aPBx=aLPB.First(); |
| 93 | } |
| 94 | //DEBt |
| 95 | if (aNbPB==1) { |
| 96 | aPB=aLPB.First(); |
| 97 | aPB->Indices(nV1, nV2); |
| 98 | bV1=myDS->IsNewShape(nV1); |
| 99 | bV2=myDS->IsNewShape(nV2); |
| 100 | // |
| 101 | if (!(bV1 || bV2)) { |
| 102 | nE=aPB->OriginalEdge(); |
| 103 | aPB->SetEdge(nE); |
| 104 | continue; |
| 105 | } |
| 106 | } |
| 107 | // |
| 108 | aItPB.Initialize(aLPB); |
| 109 | for (; aItPB.More(); aItPB.Next()) { |
| 110 | aPB=aItPB.Value(); |
| 111 | const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB); |
| 112 | bCB=!aCB.IsNull(); |
| 113 | if (bCB) { |
| 114 | myDS->SortPaveBlocks(aCB); |
| 115 | aPB=aCB->PaveBlock1(); |
| 116 | } |
| 117 | // |
| 118 | if (aMPB.Add(aPB)) { |
| 119 | nE=aPB->OriginalEdge(); |
| 120 | aPB->Indices(nV1, nV2); |
| 121 | aPB->Range(aT1, aT2); |
| 122 | // |
| 123 | nSp = SplitEdge(nE, nV1, aT1, nV2, aT2); |
| 124 | // |
| 125 | if (bCB) { |
| 126 | aCB->SetEdge(nSp); |
| 127 | } |
| 128 | else { |
| 129 | aPB->SetEdge(nSp); |
| 130 | } |
| 131 | }// if (aMPB.Add(aPB)) { |
| 132 | }// for (; aItPB.More(); aItPB.Next()) { |
| 133 | }// for (i=0; i<aNbPBP; ++i) { |
| 134 | // |
| 135 | //-----------------------------------------------------scope t |
| 136 | aMPB.Clear(); |
| 137 | aAllocator.Nullify(); |
| 138 | } |
| 139 | |
| 140 | //======================================================================= |
| 141 | // function: SplitEdge |
| 142 | // purpose: |
| 143 | //======================================================================= |
| 144 | Standard_Integer BOPAlgo_PaveFiller::SplitEdge(const Standard_Integer nE, |
| 145 | const Standard_Integer nV1, |
| 146 | const Standard_Real aT1, |
| 147 | const Standard_Integer nV2, |
| 148 | const Standard_Real aT2) |
| 149 | { |
| 150 | Standard_Integer nSp; |
| 151 | TopoDS_Vertex aV1, aV2; |
| 152 | TopoDS_Edge aE, aSp; |
| 153 | BOPDS_ShapeInfo aSI; |
| 154 | // |
| 155 | aSI.SetShapeType(TopAbs_EDGE); |
| 156 | // |
| 157 | aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
| 158 | aE.Orientation(TopAbs_FORWARD); |
| 159 | // |
| 160 | aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1))); |
| 161 | aV1.Orientation(TopAbs_FORWARD); |
| 162 | // |
| 163 | aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2))); |
| 164 | aV2.Orientation(TopAbs_REVERSED); |
| 165 | // |
| 166 | BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp); |
| 167 | // |
| 168 | aSI.SetShape(aSp); |
| 169 | // |
| 170 | Bnd_Box& aBox=aSI.ChangeBox(); |
| 171 | BRepBndLib::Add(aSp, aBox); |
| 172 | // |
| 173 | nSp=myDS->Append(aSI); |
| 174 | return nSp; |
| 175 | } |
| 176 | |
| 177 | //======================================================================= |
| 178 | // function: MakePCurves |
| 179 | // purpose: |
| 180 | //======================================================================= |
| 181 | void BOPAlgo_PaveFiller::MakePCurves() |
| 182 | { |
| 183 | Standard_Integer i, nF1, nF2, aNbC, k, nE, aNbFF, aNbFI; |
| 184 | BOPDS_ListIteratorOfListOfPaveBlock aItLPB; |
| 185 | BOPDS_MapIteratorOfMapOfPaveBlock aItMPB; |
| 186 | TopoDS_Face aF1F, aF2F; |
| 187 | // |
| 188 | myErrorStatus=0; |
| 189 | // |
| 190 | // 1. Process Common Blocks |
| 191 | const BOPDS_VectorOfFaceInfo& aFIP=myDS->FaceInfoPool(); |
| 192 | // |
| 193 | aNbFI=aFIP.Extent(); |
| 194 | for (i=0; i<aNbFI; ++i) { |
| 195 | const BOPDS_FaceInfo& aFI=aFIP(i); |
| 196 | nF1=aFI.Index(); |
| 197 | // |
| 198 | aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1))); |
| 199 | aF1F.Orientation(TopAbs_FORWARD); |
| 200 | // In |
| 201 | const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn(); |
| 202 | aItMPB.Initialize(aMPBIn); |
| 203 | for(; aItMPB.More(); aItMPB.Next()) { |
| 204 | const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value(); |
| 205 | nE=aPB->Edge(); |
| 206 | const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
| 207 | // |
| 208 | BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aF1F); |
| 209 | } |
| 210 | // On |
| 211 | const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn(); |
| 212 | aItMPB.Initialize(aMPBOn); |
| 213 | for(; aItMPB.More(); aItMPB.Next()) { |
| 214 | const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value(); |
| 215 | if (myDS->IsCommonBlockOnEdge(aPB)) { |
| 216 | nE=aPB->Edge(); |
| 217 | const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
| 218 | // |
| 219 | BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aF1F); |
| 220 | } |
| 221 | } |
| 222 | } |
| 223 | // |
| 224 | if (!mySectionAttribute.PCurveOnS1() && |
| 225 | !mySectionAttribute.PCurveOnS2()) { |
| 226 | return; |
| 227 | } |
| 228 | // |
| 229 | // 2. Process section edges |
| 230 | BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF(); |
| 231 | aNbFF=aFFs.Extent(); |
| 232 | for (i=0; i<aNbFF; ++i) { |
| 233 | const BOPDS_InterfFF& aFF=aFFs(i); |
| 234 | aFF.Indices(nF1, nF2); |
| 235 | // |
| 236 | aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1))); |
| 237 | aF1F.Orientation(TopAbs_FORWARD); |
| 238 | aF2F=(*(TopoDS_Face *)(&myDS->Shape(nF2))); |
| 239 | aF2F.Orientation(TopAbs_FORWARD); |
| 240 | // |
| 241 | const BOPDS_VectorOfCurve& aVNC=aFF.Curves(); |
| 242 | aNbC=aVNC.Extent(); |
| 243 | for (k=0; k<aNbC; ++k) { |
| 244 | const BOPDS_Curve& aNC=aVNC(k); |
| 245 | const BOPDS_ListOfPaveBlock& aLPB=aNC.PaveBlocks(); |
| 246 | aItLPB.Initialize(aLPB); |
| 247 | for(; aItLPB.More(); aItLPB.Next()) { |
| 248 | const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value(); |
| 249 | nE=aPB->Edge(); |
| 250 | const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); |
| 251 | // |
| 252 | if (mySectionAttribute.PCurveOnS1()) { |
| 253 | BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aF1F); |
| 254 | UpdateVertices(aE, aF1F); |
| 255 | } |
| 256 | // |
| 257 | if (mySectionAttribute.PCurveOnS2()) { |
| 258 | BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aE, aF2F); |
| 259 | UpdateVertices(aE, aF2F); |
| 260 | } |
| 261 | } |
| 262 | } |
| 263 | } |
| 264 | } |
| 265 | |
| 266 | //======================================================================= |
| 267 | // function: RefineFaceInfoOn |
| 268 | // purpose: |
| 269 | //======================================================================= |
| 270 | void BOPAlgo_PaveFiller::RefineFaceInfoOn() |
| 271 | { |
| 272 | Standard_Integer aNbPBP; |
| 273 | // |
| 274 | myErrorStatus=0; |
| 275 | // |
| 276 | BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool(); |
| 277 | aNbPBP=aPBP.Extent(); |
| 278 | if(!aNbPBP) { |
| 279 | return; |
| 280 | } |
| 281 | // |
| 282 | Standard_Boolean bV1, bV2; |
| 283 | Standard_Integer i, nV1, nV2, aNbPB; |
| 284 | Handle(BOPDS_PaveBlock) aPB; |
| 285 | // |
| 286 | for (i=0; i<aNbPBP; ++i) { |
| 287 | BOPDS_ListOfPaveBlock& aLPB=aPBP(i); |
| 288 | // |
| 289 | aNbPB=aLPB.Extent(); |
| 290 | if (aNbPB==1) { |
| 291 | aPB=aLPB.First(); |
| 292 | aPB->Indices(nV1, nV2); |
| 293 | bV1=myDS->IsNewShape(nV1); |
| 294 | bV2=myDS->IsNewShape(nV2); |
| 295 | // |
| 296 | if (!(bV1 || bV2)) { |
| 297 | if (!myDS->IsCommonBlock(aPB)) { |
| 298 | // the PB seems to be untouced |
| 299 | aLPB.Clear(); |
| 300 | continue; |
| 301 | } |
| 302 | }//if (!(bV1 || bV2)) { |
| 303 | }//if (aNbPB==1) { |
| 304 | }//for (i=0; i<aNbPBP; ++i) { |
| 305 | myDS->RefineFaceInfoOn(); |
| 306 | } |
| 307 | |
| 308 | //======================================================================= |
| 309 | //function : UpdateVertices |
| 310 | //purpose : update tolerances of vertices comparing extremities of |
| 311 | // 3d and 2d curves |
| 312 | //======================================================================= |
| 313 | void UpdateVertices(const TopoDS_Edge& aE, const TopoDS_Face& aF) |
| 314 | { |
| 315 | Standard_Integer j; |
| 316 | Standard_Real aT[2], aUx, aVx, aTolV2, aD2, aD; |
| 317 | gp_Pnt aP3D, aP3Dx; |
| 318 | gp_Pnt2d aP2Dx; |
| 319 | Handle(Geom_Surface) aS; |
| 320 | Handle(Geom_Curve) aC3D; |
| 321 | Handle(Geom2d_Curve) aC2D; |
| 322 | TopoDS_Edge aEf; |
| 323 | TopoDS_Vertex aV[2]; |
| 324 | BRep_Builder aBB; |
| 325 | // |
| 326 | aEf=aE; |
| 327 | aEf.Orientation(TopAbs_FORWARD); |
| 328 | // |
| 329 | TopExp::Vertices(aEf, aV[0], aV[1]); |
| 330 | // |
| 331 | aS=BRep_Tool::Surface(aF); |
| 332 | aC3D=BRep_Tool::Curve(aEf, aT[0], aT[1]); |
| 333 | aC2D=BRep_Tool::CurveOnSurface(aEf, aF, aT[0], aT[1]); |
| 334 | // |
| 335 | for (j=0; j<2; ++j) { |
| 336 | aTolV2=BRep_Tool::Tolerance(aV[j]); |
| 337 | aTolV2=aTolV2*aTolV2; |
| 338 | // |
| 339 | aC3D->D0(aT[j], aP3D); |
| 340 | aC2D->D0(aT[j], aP2Dx); |
| 341 | aP2Dx.Coord(aUx, aVx); |
| 342 | aS->D0(aUx, aVx, aP3Dx); |
| 343 | aD2=aP3D.SquareDistance(aP3Dx); |
| 344 | if (aD2>aTolV2) { |
| 345 | aD=sqrt(aD2); |
| 346 | aBB.UpdateVertex(aV[j], aD); |
| 347 | } |
| 348 | } |
| 349 | } |
| 350 | |