0030497: [REGRESSION] Mesh - wrong Poly_Polygon3D within local selection of located...
[occt.git] / src / BRepMesh / BRepMesh_ShapeVisitor.cxx
CommitLineData
7bd071ed 1// Created on: 2016-04-07
2// Copyright (c) 2016 OPEN CASCADE SAS
3// Created by: Oleg AGASHIN
4//
5// This file is part of Open CASCADE Technology software library.
6//
7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16#include <BRepMesh_ShapeVisitor.hxx>
17#include <TopoDS.hxx>
18#include <TopoDS_Edge.hxx>
19#include <TopoDS_Face.hxx>
20#include <TopoDS_Wire.hxx>
21#include <TopoDS_Vertex.hxx>
22#include <TopExp.hxx>
23#include <ShapeAnalysis.hxx>
24#include <TopExp_Explorer.hxx>
25#include <IMeshData_Edge.hxx>
26#include <IMeshData_Wire.hxx>
27#include <IMeshData_Face.hxx>
28#include <ShapeAnalysis_Wire.hxx>
29#include <ShapeAnalysis_WireOrder.hxx>
30#include <ShapeExtend_WireData.hxx>
31#include <Precision.hxx>
32#include <IMeshData_Status.hxx>
33#include <IMeshTools_Context.hxx>
34#include <BRepTools.hxx>
35
36//=======================================================================
37// Function: Constructor
38// Purpose :
39//=======================================================================
40BRepMesh_ShapeVisitor::BRepMesh_ShapeVisitor (const Handle (IMeshData_Model)& theModel)
41: myModel (theModel),
42 myDEdgeMap(1, new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE))
43{
44}
45
46//=======================================================================
47// Function: Destructor
48// Purpose :
49//=======================================================================
50BRepMesh_ShapeVisitor::~BRepMesh_ShapeVisitor ()
51{
52}
53
54//=======================================================================
55// Function: Visit (edge)
56// Purpose :
57//=======================================================================
58void BRepMesh_ShapeVisitor::Visit(const TopoDS_Edge& theEdge)
59{
967d2f4f 60 if (!myDEdgeMap.IsBound (theEdge))
61 {
62 myModel->AddEdge (theEdge);
63 myDEdgeMap.Bind (theEdge, myModel->EdgesNb () - 1);
64 }
7bd071ed 65}
66
67//=======================================================================
68// Function: Visit (face)
69// Purpose :
70//=======================================================================
71void BRepMesh_ShapeVisitor::Visit (const TopoDS_Face& theFace)
72{
73 BRepTools::Update(theFace);
74 const IMeshData::IFaceHandle& aDFace = myModel->AddFace (theFace);
75
76 // Outer wire should always be the first in the model.
77 TopoDS_Wire aOuterWire = ShapeAnalysis::OuterWire (theFace);
78 if (!addWire (aOuterWire, aDFace))
79 {
80 aDFace->SetStatus (IMeshData_Failure);
81 return;
82 }
83
84 TopExp_Explorer aWireIt (theFace, TopAbs_WIRE);
85 for (; aWireIt.More (); aWireIt.Next ())
86 {
87 const TopoDS_Wire& aWire = TopoDS::Wire (aWireIt.Current ());
88 if (aWire.IsSame(aOuterWire))
89 {
90 continue;
91 }
92
93 if (!addWire (aWire, aDFace))
94 {
95 // If there is a failure on internal wire, just skip it.
96 // The most significant is an outer wire.
97 aDFace->SetStatus (IMeshData_UnorientedWire);
98 }
99 }
100}
101
102//=======================================================================
103// Function: addWire
104// Purpose :
105//=======================================================================
106Standard_Boolean BRepMesh_ShapeVisitor::addWire (
107 const TopoDS_Wire& theWire,
108 const IMeshData::IFaceHandle& theDFace)
109{
110 if (theWire.IsNull())
111 {
112 return Standard_False;
113 }
114
115 Handle(ShapeExtend_WireData) aWireData = new ShapeExtend_WireData(theWire, Standard_True, Standard_False);
116 ShapeAnalysis_Wire aWireTool (aWireData, theDFace->GetFace (), Precision::Confusion ());
117
118 ShapeAnalysis_WireOrder aOrderTool;
119 aWireTool.CheckOrder (aOrderTool, Standard_True, Standard_False);
120 if (aWireTool.LastCheckStatus(ShapeExtend_FAIL))
121 {
122 return Standard_False;
123 }
124
125 if (aWireTool.LastCheckStatus(ShapeExtend_DONE3))
126 {
127 theDFace->SetStatus(IMeshData_UnorientedWire);
128 }
129
130 const Standard_Integer aEdgesNb = aOrderTool.NbEdges ();
131 if (aEdgesNb != aWireData->NbEdges())
132 {
133 return Standard_False;
134 }
135
136 const IMeshData::IWireHandle& aDWire = theDFace->AddWire (theWire, aEdgesNb);
137 for (Standard_Integer i = 1; i <= aEdgesNb; ++i)
138 {
139 const Standard_Integer aEdgeIndex = aOrderTool.Ordered (i);
140 const TopoDS_Edge& aEdge = aWireData->Edge (aEdgeIndex);
141 if (aEdge.Orientation() != TopAbs_EXTERNAL)
142 {
143 const IMeshData::IEdgeHandle& aDEdge = myModel->GetEdge (myDEdgeMap.Find (aEdge));
144
145 aDEdge->AddPCurve (theDFace.get(), aEdge.Orientation());
146 aDWire->AddEdge (aDEdge.get(), aEdge.Orientation());
147 }
148 }
149
150 return Standard_True;
151}