#include <BRepBuilderAPI_MakeEdge.hxx>
#include <limits>
+
+#include <BRepLib_MakeEdge.hxx>
+#include <BRepLib_MakeWire.hxx>
+#include <BRep_Builder.hxx>
+
IMPLEMENT_STANDARD_HANDLE( HYDROData_DTM, HYDROData_Bathymetry )
IMPLEMENT_STANDARD_RTTIEXT( HYDROData_DTM, HYDROData_Bathymetry )
{
SetDouble( DataTag_SpatialStep, theSpatialStep );
}
-#include <BRepLib_MakeEdge.hxx>
-#include <BRepLib_MakeWire.hxx>
-//#include <BRepLib_MakeFace.hxx>
-#include <BRep_Builder.hxx>
-#include <GeomProjLib.hxx>
-#include <Geom_TrimmedCurve.hxx>
-#include <Geom_Plane.hxx>
-#include <BRepTools_WireExplorer.hxx>
-#include <TopTools_IndexedMapOfShape.hxx>
-#include <BRepBuilderAPI_MakeFace.hxx>
+
void HYDROData_DTM::PointToWire(const AltitudePoints& pnts, TopoDS_Wire& W )
{
BRepLib_MakeWire WM;
W = WM.Wire();
}
-static void ProjWireOnPlane(const TopoDS_Wire& inpWire, const Handle_Geom_Plane& RefPlane, TopoDS_Wire& outWire)
-{
- BRepTools_WireExplorer ex(TopoDS::Wire(inpWire.Oriented(TopAbs_FORWARD)));
- BRepLib_MakeWire WM;
- for (;ex.More();ex.Next())
+TopoDS_Compound HYDROData_DTM::Create3DShape(const AltitudePoints& left,
+ const AltitudePoints& right,
+ const std::vector<AltitudePoints>& main_profiles)
+{
+ BRep_Builder BB;
+ TopoDS_Compound cmp;
+ BB.MakeCompound(cmp);
+ TopoDS_Wire LWire, RWire;
+ PointToWire(left, LWire);
+ PointToWire(right, RWire);
+ BB.Add(cmp, LWire.Oriented(TopAbs_FORWARD));
+
+ for (int k = 0; k < main_profiles.size(); k++)
{
- const TopoDS_Edge& CE = ex.Current();
- double f, l;
- Handle(Geom_Curve) C3d = BRep_Tool::Curve(CE, f, l);
- Handle(Geom_Curve) ProjectedCurve = GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d, f, l), RefPlane, RefPlane->Position().Direction(), Standard_True);
- TopoDS_Edge ProjEdge = BRepLib_MakeEdge(ProjectedCurve);
- WM.Add(ProjEdge); //auto sharing between edges if vertex is coincident
+ TopoDS_Wire W;
+ PointToWire(main_profiles[k], W);
+ TopAbs_Orientation Ori = TopAbs_INTERNAL;
+ if (k == 0 || k == main_profiles.size() - 1)
+ Ori = TopAbs_FORWARD;
+ BB.Add(cmp, W.Oriented(Ori));
}
- outWire = WM.Wire();
- outWire.Orientation(inpWire.Orientation()); //take from the original wire
-}
+ BB.Add(cmp, RWire.Oriented(TopAbs_FORWARD));
+ //yes, add subshapes in this order (left + profiles + right)
+ //otherwise the projected wire will be non-manifold!!!
+
+ return cmp;
+}
void HYDROData_DTM::Update()
{
if( ddz>EPS && step>EPS )
points = Interpolate( profiles, ddz, step, left, right, main_profiles );
+ TopoDS_Compound cmp = Create3DShape( left, right, main_profiles);
- BRep_Builder BB;
- TopoDS_Compound cmp;
- BB.MakeCompound(cmp);
- TopoDS_Wire LWire, RWire;
- PointToWire(left, LWire);
- PointToWire(right, RWire);
- BB.Add(cmp, LWire.Oriented(TopAbs_FORWARD));
-
- for (int k = 0; k < main_profiles.size(); k++)
- {
- TopoDS_Wire W;
- PointToWire(main_profiles[k], W);
- TopAbs_Orientation Ori = TopAbs_INTERNAL;
- if (k == 0 || k == main_profiles.size() - 1)
- Ori = TopAbs_FORWARD;
- BB.Add(cmp, W.Oriented(Ori));
- }
-
- BB.Add(cmp, RWire.Oriented(TopAbs_FORWARD));
- //in this order (left + profiles + right)
- //otherwise the projected wire will be non-manifold!!!
-
- //cmp = 3d pres
-
- Handle_Geom_Plane refpl = new Geom_Plane(gp_Pnt(0,0,0), gp_Dir(0,0,1));
- BRepLib_MakeWire WM;
- TopoDS_Iterator it(cmp);
- TopTools_IndexedMapOfShape IntW;
- for (;it.More(); it.Next())
- {
- const TopoDS_Wire& W = TopoDS::Wire(it.Value());
- if (W.Orientation() != TopAbs_INTERNAL)
- WM.Add(W);
- else
- IntW.Add(W);
- }
-
- TopoDS_Wire outW;
- ProjWireOnPlane(WM.Wire(), refpl, outW);
- BRepBuilderAPI_MakeFace mf(refpl, outW); //check inside is true by def
- TopoDS_Face outF = mf.Face();
-
- ///!!! the internal wires cant be added with 'internal' ori.
- // it's possible to do with brep builder yet the result will not be correct!
- // more proper way is to use BOP operation here.
- for (int i = 1; i <= IntW.Extent(); i++)
- {
- TopoDS_Wire outIW;
- const TopoDS_Wire& W = TopoDS::Wire(IntW(i));
- ProjWireOnPlane(W, refpl, outIW);
- BB.Add(outF, outIW);
- }
-
- //outF == 2d pres
+ SetShape(DataTag_DTM_Shape, cmp); //more safe way is to add each wire (left/right banks etc. with separate tag)
SetAltitudePoints( points );
- //SetTopShape(); //2d
- //this->SetShape(cmp); //3d
}
#include "HYDROData_IProfilesInterpolator.h"
#include "HYDROData_Tool.h"
#include "HYDROData_DTM.h"
+#include <HYDROData_Bathymetry.h>
#include <TDataStd_RealArray.hxx>
#include <BRepExtrema_ExtCC.hxx>
#include <BRepCheck_Analyzer.hxx>
+#include <BRepLib_MakeEdge.hxx>
+#include <BRepLib_MakeWire.hxx>
+#include <BRep_Builder.hxx>
+#include <GeomProjLib.hxx>
+#include <Geom_TrimmedCurve.hxx>
+#include <Geom_Plane.hxx>
+#include <BRepTools_WireExplorer.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <BRepBuilderAPI_MakeFace.hxx>
+
#include <gp.hxx>
#include <gp_Ax1.hxx>
#include <gp_Ax2.hxx>
if( profiles.Length() < 2 )
return false;
- std::vector<TopoDS_Wire> profiles3d;
+ /*std::vector<TopoDS_Wire> profiles3d;
profiles3d.reserve(profiles.Length());
// Pre-processing
const TopoDS_Shape& aProfileShape = aProfile->GetShape3D();
//TopExp_Explorer exp(aProfileShape, TopAbs_EDGE);
profiles3d.push_back( TopoDS::Wire(aProfileShape) );
- }
+ }*/
- TopoDS_Edge aLeftBank, aRightBank;
- //TODO: theDTM->CreateBankShapes( aLeftBank, aRightBank );
- return CreatePresentations( aLeftBank, aRightBank, profiles3d, thePrs );
+ CreatePresentationsIntern( theDTM, thePrs );
+ return true;
}
void HYDROData_Stream::UpdatePrs( const Handle_HYDROData_DTM& theDTM )
}
}
-
-bool HYDROData_Stream::CreatePresentations( const TopoDS_Edge& theLeftBank,
- const TopoDS_Edge& theRightBank,
- const std::vector<TopoDS_Wire>& theProfiles3d,
- PrsDefinition& thePrs )
+static void ProjWireOnPlane(const TopoDS_Wire& inpWire, const Handle_Geom_Plane& RefPlane, TopoDS_Wire& outWire)
{
- //thePrs.myLeftBank = theLeftBank;
- //thePrs.myRightBank = theRightBank;
- //
- //BRep_Builder aBB;
- //TopoDS_Compound aCmp;
- //aBB.MakeCompound(aCmp);
- //for (size_t i = 0; i < theProfiles3d.size(); i++ )
- // aBB.Add(aCmp, theProfiles3d[i]);
- //
- //aBB.Add(aCmp, theLeftBank);
- //aBB.Add(aCmp, theRightBank);
- //
- //thePrs.myPrs3D = aCmp; //3d pres
- //
- /*Handle_Geom_Plane RefPlane = new Geom_Plane(gp_Pnt(0,0,0), gp_Dir(0,0,1));
- TopoDS_Vertex V1, V2;
- TopoDS_Wire W;
- ProjEdgeOnPlane(theProfiles3d[0], RefPlane, W, V1, V2);*/
-
- /* Handle_Geom_Plane RefPlane = new Geom_Plane(gp_Pnt(0,0,0), gp_Dir(0,0,1));
- std::vector<TopoDS_Edge> internProf;
- internProf.reserve(theProfiles3d.size() - 2);
-
- //project internal edges/profiles
- for (size_t i = 1; i < theProfiles3d.size() - 1; i++ )
+ BRepTools_WireExplorer ex(TopoDS::Wire(inpWire.Oriented(TopAbs_FORWARD)));
+ BRepLib_MakeWire WM;
+ for (;ex.More();ex.Next())
{
- TopoDS_Edge ProjEdge;
- ProjEdgeOnPlane(theProfiles3d[i], RefPlane, ProjEdge, TopoDS_Vertex(), TopoDS_Vertex());
- internProf.push_back (TopoDS::Edge(ProjEdge.Oriented(TopAbs_INTERNAL)));
+ const TopoDS_Edge& CE = ex.Current();
+ double f, l;
+ Handle(Geom_Curve) C3d = BRep_Tool::Curve(CE, f, l);
+ Handle(Geom_Curve) ProjectedCurve = GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d, f, l), RefPlane, RefPlane->Position().Direction(), Standard_True);
+ TopoDS_Edge ProjEdge = BRepLib_MakeEdge(ProjectedCurve);
+ WM.Add(ProjEdge); //auto sharing between edges if vertex is coincident
}
-
- TopoDS_Edge ProjEdgeIn, ProjEdgeOut;
- TopoDS_Vertex V1In, V2In, V1Out, V2Out;
+ outWire = WM.Wire();
+ outWire.Orientation(inpWire.Orientation()); //take from the original wire
+}
- ProjEdgeOnPlane(theProfiles3d.front(), RefPlane, ProjEdgeIn, TopoDS_Vertex(), TopoDS_Vertex());
- TopExp::Vertices(ProjEdgeIn, V1In, V2In);
- ProjEdgeOnPlane(theProfiles3d.back(), RefPlane, ProjEdgeOut, TopoDS_Vertex(), TopoDS_Vertex());
- TopExp::Vertices(ProjEdgeOut, V1Out, V2Out);
+static void Get2dFaceFrom3dPres(const TopoDS_Compound& cmp, TopoDS_Face& outF )
+{
+ Handle_Geom_Plane refpl = new Geom_Plane(gp_Pnt(0,0,0), gp_Dir(0,0,1));
+ BRepLib_MakeWire WM;
+ TopoDS_Iterator it(cmp);
+ //TopTools_IndexedMapOfShape IntW;
+ for (;it.More(); it.Next())
+ {
+ const TopoDS_Wire& W = TopoDS::Wire(it.Value());
+ if (W.Orientation() != TopAbs_INTERNAL)
+ {
+ //use list of edges to protect againts non-manifold cases.
+ //auto sharing between edges will be added automatically
+ TopTools_IndexedMapOfShape ME;
+ TopTools_ListOfShape LE;
+ TopExp::MapShapes(W, TopAbs_EDGE, ME);
+ for (int i = 1; i <= ME.Extent(); i++)
+ LE.Append(ME(i));
+ WM.Add(LE);
+ }
+ //else
+ // IntW.Add(W);
+ }
- TopoDS_Edge ProjEdgeLeftB, ProjEdgeRightB;
- ProjEdgeOnPlane(theLeftBank, RefPlane, ProjEdgeLeftB, V1In, V1Out);
- ProjEdgeOnPlane(theRightBank, RefPlane, ProjEdgeRightB, V2In, V2Out);
+ TopoDS_Wire outW;
+ ProjWireOnPlane(WM.Wire(), refpl, outW);
+ BRepBuilderAPI_MakeFace mf(refpl, outW); //check inside is true by def
+ outF = mf.Face();
- BRepLib_MakeWire WM(ProjEdgeIn, ProjEdgeOut, ProjEdgeLeftB, ProjEdgeRightB);
- for (size_t i = 0; i < internProf.size(); i++ )
- WM.Add(internProf[i]);
+ ///!!! the internal wires cant be added with 'internal' ori.
+ // it's possible to do with brep builder yet the result will not be correct!
+ // more proper way is to use BOP operation here.
+ /*for (int i = 1; i <= IntW.Extent(); i++)
+ {
+ TopoDS_Wire outIW;
+ const TopoDS_Wire& W = TopoDS::Wire(IntW(i));
+ ProjWireOnPlane(W, refpl, outIW);
+ BB.Add(outF, outIW);
+ }*/
+}
- TopoDS_Face outF = BRepLib_MakeFace(RefPlane, WM.Wire()).Face();
- thePrs.myPrs2D = outF;*/
+void HYDROData_Stream::CreatePresentationsIntern( const Handle_HYDROData_DTM& theDTM,
+ PrsDefinition& thePrs )
+{
+ TopoDS_Compound cmp = TopoDS::Compound(theDTM->GetShape(HYDROData_DTM::DataTag_DTM_Shape));
+ thePrs.myPrs3D = cmp;
+ NCollection_Sequence<TopoDS_Wire> WW;
+ TopoDS_Iterator it(cmp);
+ for (;it.More(); it.Next())
+ WW.Append(TopoDS::Wire(it.Value()));
+
+ //same order as in HYDROData_DTM::Update()
+ thePrs.myLeftBank = WW.First();
+ thePrs.myRightBank = WW.Last();
+ thePrs.myInlet = WW(1); //TODO check this!!
+ thePrs.myOutlet = WW(WW.Length() - 1);
+
+ TopoDS_Face outF;
+ Get2dFaceFrom3dPres(cmp, outF);
+ thePrs.myPrs2D = outF;
- return true;
/*if ( theArrayOfFPnt.IsNull() || theArrayOfLPnt.IsNull() || theArrOfProfiles.IsNull() ) {
return false;
}
#endif
return true;*/
+}
+
+void HYDROData_Stream::CreatePresentations( const Handle(TColgp_HArray1OfPnt) theArrayOfFPnt,
+ const Handle(TColgp_HArray1OfPnt) theArrayOfLPnt,
+ const Handle(TopTools_HArray1OfShape) theArrOfProfiles,
+ PrsDefinition& thePrs )
+{
+
+ HYDROData_Bathymetry::AltitudePoints left;
+ for (int i = theArrayOfLPnt->Lower(); i <= theArrayOfLPnt->Upper(); i++)
+ {
+ left.push_back(HYDROData_Bathymetry::AltitudePoint(theArrayOfLPnt->Value(i).X(),
+ theArrayOfLPnt->Value(i).Y(),
+ theArrayOfLPnt->Value(i).Z()));
+ }
+
+ HYDROData_Bathymetry::AltitudePoints right;
+ for (int i = theArrayOfFPnt->Lower(); i <= theArrayOfFPnt->Upper(); i++)
+ {
+ right.push_back(HYDROData_Bathymetry::AltitudePoint(theArrayOfFPnt->Value(i).X(),
+ theArrayOfFPnt->Value(i).Y(),
+ theArrayOfFPnt->Value(i).Z()));
+ }
+
+ std::vector<HYDROData_Bathymetry::AltitudePoints> dummy;
+ TopoDS_Compound cmp = HYDROData_DTM::Create3DShape(left, right, dummy);
+ TopoDS_Iterator it(cmp);
+ thePrs.myLeftBank = TopoDS::Wire(it.Value());
+ it.Next();
+ thePrs.myRightBank = TopoDS::Wire(it.Value());
+
+ thePrs.myInlet = TopoDS::Wire(theArrOfProfiles->Value(theArrOfProfiles->Lower())); //TODO check that
+ thePrs.myOutlet = TopoDS::Wire(theArrOfProfiles->Value(theArrOfProfiles->Upper()));
+
+ //make new compound so it's shapes will be in known order to build correct projection
+ BRep_Builder BB;
+ TopoDS_Compound newCmp;
+ BB.MakeCompound(newCmp);
+ BB.Add(newCmp, thePrs.myLeftBank);
+ BB.Add(newCmp, thePrs.myInlet);
+ BB.Add(newCmp, thePrs.myOutlet);
+ BB.Add(newCmp, thePrs.myRightBank);
+
+ thePrs.myPrs3D = newCmp;
+
+ Get2dFaceFrom3dPres( newCmp, TopoDS::Face(thePrs.myPrs2D) );
+
}
\ No newline at end of file