1 // Copyright (C) 2013-2022 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
20 #include "GEOMImpl_ConformityDriver.hxx"
23 #include "GEOMImpl_IConformity.hxx"
26 #include <utilities.h>
27 #include <Basics_Utils.hxx>
30 #include "GEOM_Function.hxx"
31 #include "GEOMImpl_Types.hxx"
33 #include <BOPAlgo_ArgumentAnalyzer.hxx>
34 #include <BRepTools.hxx>
35 #include <BRepTools_ReShape.hxx>
36 #include <BRepLib.hxx>
37 #include <BRep_Tool.hxx>
39 #include <TopExp_Explorer.hxx>
40 #include <GEOMUtils.hxx>
41 #include <TColStd_HArray2OfInteger.hxx>
45 //=======================================================================
46 //function : ConvertShapesToIndices
47 //purpose : Convert sub-shapes of shapes to sequence of indices
48 //=======================================================================
49 Handle(TColStd_HArray1OfInteger) ConvertShapesToIndices(const TopoDS_Shape& theShape,
50 const TopTools_ListOfShape& theShapes)
52 Handle(TColStd_HArray1OfInteger) aSeqOfIDs = new TColStd_HArray1OfInteger(1, theShapes.Size());
54 TopTools_IndexedMapOfShape anIndices;
55 TopExp::MapShapes(theShape, anIndices);
57 TopTools_ListIteratorOfListOfShape itSub(theShapes);
58 for (int index = 1; itSub.More(); itSub.Next(), ++index)
60 int id = anIndices.FindIndex(itSub.Value());
61 aSeqOfIDs->SetValue(index, id);
67 //=======================================================================
68 //function : ConvertShapesToIndices
69 //purpose : Convert list of pair shapes to sequence of indices
70 //=======================================================================
71 Handle(TColStd_HArray2OfInteger) ConvertShapesToIndices(
72 const TopoDS_Shape& theShape,
73 const NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>>& theShapes)
75 Handle(TColStd_HArray2OfInteger) aSeqOfIDs = new TColStd_HArray2OfInteger(1, theShapes.Size(), 1, 2);
77 TopTools_IndexedMapOfShape anIndices;
78 TopExp::MapShapes(theShape, anIndices);
80 NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>>::Iterator itSub(theShapes);
81 for (int index = 1; itSub.More(); itSub.Next(), ++index)
83 int anID1 = anIndices.FindIndex(itSub.Value().first);
84 aSeqOfIDs->SetValue(index, 1, anID1);
86 int anID2 = anIndices.FindIndex(itSub.Value().second);
87 aSeqOfIDs->SetValue(index, 2, anID2);
94 //=======================================================================
97 //=======================================================================
98 const Standard_GUID& GEOMImpl_ConformityDriver::GetID()
100 static Standard_GUID aGUID("B77BABDA-C0A1-4E65-9B1E-7EFC4448077E");
104 //=======================================================================
105 //function : GEOMImpl_ConformityDriver
107 //=======================================================================
108 GEOMImpl_ConformityDriver::GEOMImpl_ConformityDriver()
112 //=======================================================================
115 //=======================================================================
116 Standard_Integer GEOMImpl_ConformityDriver::Execute(Handle(TFunction_Logbook)& log) const
118 if (Label().IsNull()) return 0;
119 Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
120 GEOMImpl_IConformity aCI(aFunction);
122 Standard_Integer aType = aFunction->GetType();
124 Handle(GEOM_Function) aRefShape = aCI.GetShape();
125 if (aRefShape.IsNull()) return 0;
127 TopoDS_Shape aShape = aRefShape->GetValue();
131 case CONFORMITY_UPDATE_TOL:
133 Standard_Real aTolerance = updateTolerance(aShape);
134 aFunction->SetReal(CHECKCONFORMITY_RET_TOLERANCE, aTolerance);
137 case CONFORMITY_CHECK_SHAPE:
139 NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>> aFailedShape;
140 Handle(TColStd_HArray1OfInteger) aTypesOfCheck;
141 checkShape(aShape, aFailedShape, aTypesOfCheck);
143 Handle(TColStd_HArray2OfInteger) anArray = ConvertShapesToIndices(aShape, aFailedShape);
144 aFunction->SetIntegerArray(CHECKCONFORMITY_RET_TYPES_CHECKS, aTypesOfCheck);
145 aCI.SetListOfShapesIndices(anArray);
152 //=======================================================================
153 //function : checkShape
155 //=======================================================================
156 void GEOMImpl_ConformityDriver::checkShape(const TopoDS_Shape & theShape,
157 NCollection_List<std::pair<TopoDS_Shape, TopoDS_Shape>>& theFailedShape,
158 Handle(TColStd_HArray1OfInteger)& theTypesOfCheck) const
160 BOPAlgo_ArgumentAnalyzer anAnalyzer;
161 performAnalyze(theShape, anAnalyzer);
163 const BOPAlgo_ListOfCheckResult& aResult = anAnalyzer.GetCheckResult();
164 theTypesOfCheck = new TColStd_HArray1OfInteger(1, aResult.Size());
166 BOPAlgo_ListOfCheckResult::Iterator anIter(aResult);
167 for (int index = 1; anIter.More(); anIter.Next(), ++index)
169 theTypesOfCheck->SetValue(index, anIter.Value().GetCheckStatus());
170 std::pair<TopoDS_Shape, TopoDS_Shape> aPair;
171 aPair.first = anIter.Value().GetFaultyShapes1().First();
172 if (anIter.Value().GetFaultyShapes1().Size() != 1)
173 aPair.second = anIter.Value().GetFaultyShapes1().Last();
174 theFailedShape.Append(aPair);
178 //=======================================================================
179 //function : updateTolerance
181 //=======================================================================
182 Standard_Real GEOMImpl_ConformityDriver::updateTolerance(const TopoDS_Shape& theShape) const
184 Standard_Real aTolerance = INFINITY;
186 TopoDS_Shape aResShape = theShape;
188 BRepLib::UpdateTolerances(aResShape, Standard_False);
190 for (const auto& aType : { TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE })
192 for (TopExp_Explorer anExp(aResShape, aType); anExp.More(); anExp.Next())
194 Standard_Real aCurTolerance = INFINITY;
198 aCurTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(anExp.Value()));
201 aCurTolerance = BRep_Tool::Tolerance(TopoDS::Edge(anExp.Value()));
204 aCurTolerance = BRep_Tool::Tolerance(TopoDS::Face(anExp.Value()));
207 aTolerance = Min(aTolerance, aCurTolerance);
211 TopoDS_Shape aShape = theShape;
212 GEOMUtils::FixShapeTolerance(aShape, aTolerance, Standard_True);
214 Standard_Real aResTol = 0.;
215 for (const auto& aType : { TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE })
217 for (TopExp_Explorer anExp(aShape, aType); anExp.More(); anExp.Next())
219 Standard_Real aCurTolerance = INFINITY;
223 aCurTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(anExp.Value()));
226 aCurTolerance = BRep_Tool::Tolerance(TopoDS::Edge(anExp.Value()));
229 aCurTolerance = BRep_Tool::Tolerance(TopoDS::Face(anExp.Value()));
232 aResTol = Max(aResTol, aCurTolerance);
239 //=======================================================================
240 //function : performAnalyze
242 //=======================================================================
243 void GEOMImpl_ConformityDriver::performAnalyze(const TopoDS_Shape& theShape,
244 BOPAlgo_ArgumentAnalyzer& theAnalyzer) const
246 theAnalyzer.SetShape1(theShape);
248 theAnalyzer.CurveOnSurfaceMode() = Standard_True;
249 theAnalyzer.SelfInterMode() = Standard_True;
250 theAnalyzer.SmallEdgeMode() = Standard_True;
252 theAnalyzer.Perform();