FeatureSketchBased.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025 #ifndef _PreComp_
00026 # include <Bnd_Box.hxx>
00027 # include <BRep_Builder.hxx>
00028 # include <BRepBndLib.hxx>
00029 # include <BRepBuilderAPI_MakeFace.hxx>
00030 # include <BRepAdaptor_Surface.hxx>
00031 # include <BRepCheck_Analyzer.hxx>
00032 # include <BRep_Tool.hxx>
00033 # include <Geom_Plane.hxx>
00034 # include <TopoDS.hxx>
00035 # include <TopoDS_Compound.hxx>
00036 # include <TopoDS_Face.hxx>
00037 # include <TopoDS_Wire.hxx>
00038 # include <TopoDS_Vertex.hxx>
00039 # include <TopExp_Explorer.hxx>
00040 # include <gp_Pln.hxx>
00041 # include <ShapeFix_Face.hxx>
00042 # include <ShapeFix_Wire.hxx>
00043 # include <ShapeAnalysis.hxx>
00044 # include <TopTools_IndexedMapOfShape.hxx>
00045 # include <IntTools_FClass2d.hxx>
00046 # include <ShapeAnalysis_Surface.hxx>
00047 # include <ShapeFix_Shape.hxx>
00048 #endif
00049
00050
00051 #include "FeatureSketchBased.h"
00052
00053
00054 using namespace PartDesign;
00055
00056 namespace PartDesign {
00057
00058
00059 struct Wire_Compare {
00060 bool operator() (const TopoDS_Wire& w1, const TopoDS_Wire& w2)
00061 {
00062 Bnd_Box box1, box2;
00063 BRepBndLib::Add(w1, box1);
00064 box1.SetGap(0.0);
00065
00066 BRepBndLib::Add(w2, box2);
00067 box2.SetGap(0.0);
00068
00069 return box1.SquareExtent() < box2.SquareExtent();
00070 }
00071 };
00072
00073 PROPERTY_SOURCE(PartDesign::SketchBased, PartDesign::Feature)
00074
00075 SketchBased::SketchBased()
00076 {
00077 ADD_PROPERTY(Sketch,(0));
00078 }
00079
00080 bool SketchBased::isInside(const TopoDS_Wire& wire1, const TopoDS_Wire& wire2) const
00081 {
00082 Bnd_Box box1;
00083 BRepBndLib::Add(wire1, box1);
00084 box1.SetGap(0.0);
00085
00086 Bnd_Box box2;
00087 BRepBndLib::Add(wire2, box2);
00088 box2.SetGap(0.0);
00089
00090 if (box1.IsOut(box2))
00091 return false;
00092
00093 double prec = Precision::Confusion();
00094
00095 BRepBuilderAPI_MakeFace mkFace(wire1);
00096 TopoDS_Face face = validateFace(mkFace.Face());
00097 BRepAdaptor_Surface adapt(face);
00098 IntTools_FClass2d class2d(face, prec);
00099 Handle_Geom_Surface surf = new Geom_Plane(adapt.Plane());
00100 ShapeAnalysis_Surface as(surf);
00101
00102 TopExp_Explorer xp(wire2,TopAbs_VERTEX);
00103 while (xp.More()) {
00104 TopoDS_Vertex v = TopoDS::Vertex(xp.Current());
00105 gp_Pnt p = BRep_Tool::Pnt(v);
00106 gp_Pnt2d uv = as.ValueOfUV(p, prec);
00107 if (class2d.Perform(uv) == TopAbs_IN)
00108 return true;
00109
00110
00111 else
00112 return false;
00113 xp.Next();
00114 }
00115
00116 return false;
00117 }
00118
00119 TopoDS_Face SketchBased::validateFace(const TopoDS_Face& face) const
00120 {
00121 BRepCheck_Analyzer aChecker(face);
00122 if (!aChecker.IsValid()) {
00123 TopoDS_Wire outerwire = ShapeAnalysis::OuterWire(face);
00124 TopTools_IndexedMapOfShape myMap;
00125 myMap.Add(outerwire);
00126
00127 TopExp_Explorer xp(face,TopAbs_WIRE);
00128 ShapeFix_Wire fix;
00129 fix.SetFace(face);
00130 fix.Load(outerwire);
00131 fix.Perform();
00132 BRepBuilderAPI_MakeFace mkFace(fix.WireAPIMake());
00133 while (xp.More()) {
00134 if (!myMap.Contains(xp.Current())) {
00135 fix.Load(TopoDS::Wire(xp.Current()));
00136 fix.Perform();
00137 mkFace.Add(fix.WireAPIMake());
00138 }
00139 xp.Next();
00140 }
00141
00142 aChecker.Init(mkFace.Face());
00143 if (!aChecker.IsValid()) {
00144 ShapeFix_Shape fix(mkFace.Face());
00145 fix.SetPrecision(Precision::Confusion());
00146 fix.SetMaxTolerance(Precision::Confusion());
00147 fix.SetMaxTolerance(Precision::Confusion());
00148 fix.Perform();
00149 fix.FixWireTool()->Perform();
00150 fix.FixFaceTool()->Perform();
00151 return TopoDS::Face(fix.Shape());
00152 }
00153 return mkFace.Face();
00154 }
00155
00156 return face;
00157 }
00158
00159 TopoDS_Shape SketchBased::makeFace(std::list<TopoDS_Wire>& wires) const
00160 {
00161 BRepBuilderAPI_MakeFace mkFace(wires.front());
00162 const TopoDS_Face& face = mkFace.Face();
00163 if (face.IsNull())
00164 return face;
00165 gp_Dir axis(0,0,1);
00166 BRepAdaptor_Surface adapt(face);
00167 if (adapt.GetType() == GeomAbs_Plane) {
00168 axis = adapt.Plane().Axis().Direction();
00169 }
00170
00171 wires.pop_front();
00172 for (std::list<TopoDS_Wire>::iterator it = wires.begin(); it != wires.end(); ++it) {
00173 BRepBuilderAPI_MakeFace mkInnerFace(*it);
00174 const TopoDS_Face& inner_face = mkInnerFace.Face();
00175 if (inner_face.IsNull())
00176 return inner_face;
00177 gp_Dir inner_axis(0,0,1);
00178 BRepAdaptor_Surface adapt(inner_face);
00179 if (adapt.GetType() == GeomAbs_Plane) {
00180 inner_axis = adapt.Plane().Axis().Direction();
00181 }
00182
00183
00184 if (axis.Dot(inner_axis) < 0)
00185 it->Reverse();
00186 mkFace.Add(*it);
00187 }
00188 return validateFace(mkFace.Face());
00189 }
00190
00191 TopoDS_Shape SketchBased::makeFace(const std::vector<TopoDS_Wire>& w) const
00192 {
00193 if (w.empty())
00194 return TopoDS_Shape();
00195
00196
00197
00198 std::vector<TopoDS_Wire> wires = w;
00199 std::sort(wires.begin(), wires.end(), Wire_Compare());
00200 std::list<TopoDS_Wire> wire_list;
00201 wire_list.insert(wire_list.begin(), wires.rbegin(), wires.rend());
00202
00203
00204 std::list< std::list<TopoDS_Wire> > sep_wire_list;
00205 while (!wire_list.empty()) {
00206 std::list<TopoDS_Wire> sep_list;
00207 TopoDS_Wire wire = wire_list.front();
00208 wire_list.pop_front();
00209 sep_list.push_back(wire);
00210
00211 std::list<TopoDS_Wire>::iterator it = wire_list.begin();
00212 while (it != wire_list.end()) {
00213 if (isInside(wire, *it)) {
00214 sep_list.push_back(*it);
00215 it = wire_list.erase(it);
00216 }
00217 else {
00218 ++it;
00219 }
00220 }
00221
00222 sep_wire_list.push_back(sep_list);
00223 }
00224
00225 if (sep_wire_list.size() == 1) {
00226 std::list<TopoDS_Wire>& wires = sep_wire_list.front();
00227 return makeFace(wires);
00228 }
00229 else if (sep_wire_list.size() > 1) {
00230 TopoDS_Compound comp;
00231 BRep_Builder builder;
00232 builder.MakeCompound(comp);
00233 for (std::list< std::list<TopoDS_Wire> >::iterator it = sep_wire_list.begin(); it != sep_wire_list.end(); ++it) {
00234 TopoDS_Shape aFace = makeFace(*it);
00235 if (!aFace.IsNull())
00236 builder.Add(comp, aFace);
00237 }
00238
00239 return comp;
00240 }
00241 else {
00242 return TopoDS_Shape();
00243 }
00244 }
00245
00246 }