// Created on: 1994-06-07
// Created by: Bruno DUMORTIER
// Copyright (c) 1994-1999 Matra Datavision
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
-
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
#include <BRepFill_Pipe.ixx>
#include <BRep_Builder.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <BRepLib_MakeVertex.hxx>
+#include <BRepTools_Substitution.hxx>
#include <GeomFill_CorrectedFrenet.hxx>
+#include <GeomFill_Frenet.hxx>
+#include <GeomFill_DiscreteTrihedron.hxx>
#include <GeomFill_CurveAndTrihedron.hxx>
#include <BRepFill_SectionPlacement.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Iterator.hxx>
+#include <TopTools_DataMapOfShapeInteger.hxx>
+#include <TColStd_DataMapOfIntegerInteger.hxx>
+#include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
#include <Precision.hxx>
#include <Standard_NotImplemented.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Geom_OffsetCurve.hxx>
#include <Geom_BSplineCurve.hxx>
+#include <BRepBuilderAPI_Transform.hxx>
+#include <BRepBuilderAPI_Copy.hxx>
+#include <TopTools_SequenceOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <BRepLib.hxx>
+
+#include <Geom2dAdaptor_HCurve.hxx>
+#include <GeomAdaptor_HSurface.hxx>
+#include <Adaptor3d_CurveOnSurface.hxx>
+
+#include <ShapeUpgrade_RemoveLocations.hxx>
#ifdef DRAW
#include <DBRep.hxx>
static Standard_Boolean Affich = 0;
#endif
+static void ReverseModifiedEdges(TopoDS_Shape& aShape,
+ TopTools_MapOfShape& Emap)
+{
+ TopExp_Explorer Explo(aShape, TopAbs_FACE);
+ BRep_Builder BB;
+
+ for (; Explo.More(); Explo.Next())
+ {
+ TopoDS_Shape aFace = Explo.Current();
+ TopoDS_Iterator itf(aFace);
+ for (; itf.More(); itf.Next())
+ {
+ TopoDS_Shape aWire = itf.Value();
+ TopTools_ListOfShape Ledges;
+ TopoDS_Iterator itw(aWire);
+ for (; itw.More(); itw.Next())
+ Ledges.Append(itw.Value());
+
+ aWire.Free(Standard_True);
+ TopTools_ListIteratorOfListOfShape itl(Ledges);
+ for (; itl.More(); itl.Next())
+ BB.Remove(aWire, itl.Value());
+
+ for (itl.Initialize(Ledges); itl.More(); itl.Next())
+ {
+ TopoDS_Shape anEdge = itl.Value();
+ if (Emap.Contains(anEdge))
+ anEdge.Reverse();
+ BB.Add(aWire, anEdge);
+ }
+ }
+ }
+}
+
+static void UpdateTolFromTopOrBottomPCurve(const TopoDS_Face& aFace,
+ TopoDS_Edge& anEdge)
+{
+ Standard_Real fpar, lpar;
+ Handle(Geom2d_Curve) aPCurve = BRep_Tool::CurveOnSurface(anEdge, aFace, fpar, lpar);
+ if (aPCurve.IsNull())
+ return;
+
+ Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, fpar, lpar);
+ if (aCurve.IsNull())
+ return;
+
+ Handle(Geom2dAdaptor_HCurve) GAHC2d = new Geom2dAdaptor_HCurve(aPCurve, fpar, lpar);
+ Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
+ Handle(GeomAdaptor_HSurface) GAHS = new GeomAdaptor_HSurface(aSurf);
+ Adaptor3d_CurveOnSurface ConS(GAHC2d, GAHS);
+
+ Standard_Real Tol = BRep_Tool::Tolerance(anEdge);
+ Standard_Real InitTol = Tol;
+ Standard_Real TolTol = Tol*Tol;
+ const Standard_Integer NCONTROL = 22;
+ Standard_Real delta = (lpar - fpar)/NCONTROL;
+ for (Standard_Integer i = 0; i <= NCONTROL; i++)
+ {
+ Standard_Real par = fpar + i*delta;
+ gp_Pnt pnt = aCurve->Value(par);
+ gp_Pnt prj = ConS.Value(par);
+ Standard_Real sqdist = pnt.SquareDistance(prj);
+ if (sqdist > TolTol)
+ TolTol = sqdist;
+ }
+ Tol = 1.00005 * Sqrt(TolTol);
+ if (Tol >= InitTol)
+ {
+ BRep_Builder BB;
+ BB.UpdateEdge(anEdge, Tol);
+ TopoDS_Iterator itv(anEdge);
+ for (; itv.More(); itv.Next())
+ {
+ TopoDS_Vertex aVertex = TopoDS::Vertex(itv.Value());
+ BB.UpdateVertex(aVertex, Tol);
+ }
+ }
+}
+
//=======================================================================
//function : BRepFill_Pipe
//purpose :
BRepFill_Pipe::BRepFill_Pipe()
{
- myDegmax = 10;
+ myDegmax = 11;
mySegmax = 100;
+ myContinuity = GeomAbs_C2;
+ myMode = GeomFill_IsCorrectedFrenet;
+ myForceApproxC1 = Standard_False;
+
+ myCurIndexOfSectionEdge = 1;
}
BRepFill_Pipe::BRepFill_Pipe(const TopoDS_Wire& Spine,
const TopoDS_Shape& Profile,
+ const GeomFill_Trihedron aMode,
+ const Standard_Boolean ForceApproxC1,
const Standard_Boolean KPart)
+
{
- myDegmax = 10;
+ myDegmax = 11;
mySegmax = 100;
+
+ myMode = GeomFill_IsCorrectedFrenet;
+ if (aMode == GeomFill_IsFrenet ||
+ aMode == GeomFill_IsCorrectedFrenet ||
+ aMode == GeomFill_IsDiscreteTrihedron)
+ myMode = aMode;
+
+ myContinuity = GeomAbs_C2;
+ if (myMode == GeomFill_IsDiscreteTrihedron)
+ myContinuity = GeomAbs_C0;
+
+ myForceApproxC1 = ForceApproxC1;
+
+ myCurIndexOfSectionEdge = 1;
+
Perform(Spine, Profile, KPart);
}
-
//=======================================================================
//function : Perform
//purpose :
void BRepFill_Pipe::Perform(const TopoDS_Wire& Spine,
const TopoDS_Shape& Profile,
- const Standard_Boolean KPart)
+ const Standard_Boolean /*KPart*/)
{
mySections.Nullify();
BRepTools_WireExplorer wexp;
TopoDS_Shape TheProf;
-
- Handle(GeomFill_CorrectedFrenet) TLaw =
- new (GeomFill_CorrectedFrenet) ();
+ Handle(GeomFill_TrihedronLaw) TLaw;
+ switch (myMode)
+ {
+ case GeomFill_IsFrenet:
+ TLaw = new GeomFill_Frenet();
+ break;
+ case GeomFill_IsCorrectedFrenet:
+ TLaw = new GeomFill_CorrectedFrenet();
+ break;
+ case GeomFill_IsDiscreteTrihedron:
+ TLaw = new GeomFill_DiscreteTrihedron();
+ break;
+ default:
+ break;
+ }
Handle(GeomFill_CurveAndTrihedron) Loc =
new (GeomFill_CurveAndTrihedron) (TLaw);
myLoc = new (BRepFill_Edge3DLaw) (mySpine, Loc);
TopLoc_Location LocFirst(fila);
myFirst = myProfile;
if ( ! LocFirst.IsIdentity()) {
- myFirst.Location( LocFirst.Multiplied(myProfile.Location()) );
+ //myFirst.Location( LocFirst.Multiplied(myProfile.Location()) );
+ myFirst = BRepBuilderAPI_Transform(myProfile, fila, Standard_True); //copy
}
+ ShapeUpgrade_RemoveLocations RemLoc;
+ RemLoc.Remove(myFirst);
+ myFirst = RemLoc.GetResult();
+ TopLoc_Location theLoc = myFirst.Location();
+ if (!theLoc.IsIdentity())
+ {
+ TopoDS_Shape NewMyFirst = BRepBuilderAPI_Copy(myFirst);
+ RemLoc.Remove(NewMyFirst);
+ NewMyFirst = RemLoc.GetResult();
+ TopLoc_Location theIdentity;
+ NewMyFirst.Location(theIdentity);
+ myFirst = BRepBuilderAPI_Transform(NewMyFirst, theLoc.Transformation(), Standard_True);
+ }
+
myLoc->Law(myLoc->NbLaw())->GetDomain(first, last);
myLoc->Law(myLoc->NbLaw())->D0(last,M, V);
// try { // Not good, but there are no other means to test SetValues
if (! myLoc->IsClosed() || LocFirst != LocLast) {
myLast = myProfile;
if ( ! LocLast.IsIdentity()) {
- myLast.Location(LocLast.Multiplied(myProfile.Location()) );
+ //myLast.Location(LocLast.Multiplied(myProfile.Location()) );
+ myLast = BRepBuilderAPI_Transform(myProfile, fila, Standard_True); //copy
}
}
else {
myLast = myFirst;
}
+
+ RemLoc.Remove(myLast);
+ myLast = RemLoc.GetResult();
+ theLoc = myLast.Location();
+ if (!theLoc.IsIdentity())
+ {
+ TopoDS_Shape NewMyLast = BRepBuilderAPI_Copy(myLast);
+ RemLoc.Remove(NewMyLast);
+ NewMyLast = RemLoc.GetResult();
+ TopLoc_Location theIdentity;
+ NewMyLast.Location(theIdentity);
+ myLast = BRepBuilderAPI_Transform(NewMyLast, theLoc.Transformation(), Standard_True);
+ }
+
#if DRAW
if (Affich) {
DBRep::Set("theprof", TheProf);
//purpose : Construct a wire by sweeping of a point
//=======================================================================
-TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point) const
+TopoDS_Wire BRepFill_Pipe::PipeLine(const gp_Pnt& Point)
{
// Postioning
gp_Pnt P;
// Sweeping
BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
- MkSw.Build( BRepFill_Modified, GeomFill_Location, GeomAbs_C2, myDegmax, mySegmax );
+ MkSw.SetForceApproxC1(myForceApproxC1);
+ MkSw.Build( myReversedEdges, myTapes,
+ BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
TopoDS_Shape aLocalShape = MkSw.Shape();
return TopoDS::Wire(aLocalShape);
// return TopoDS::Wire(MkSw.Shape());
case TopAbs_SOLID :
case TopAbs_COMPSOLID :
- Standard_DomainError::Raise("BRepFill_Pipe::SOLID or COMPSOLID");
+ Standard_DomainError::Raise("BRepFill_Pipe::profile contains solids");
break;
case TopAbs_COMPOUND :
Handle(BRepFill_ShapeLaw) Section =
new (BRepFill_ShapeLaw) (TopoDS::Vertex(TheS));
BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
- MkSw.Build( BRepFill_Modified, GeomFill_Location, GeomAbs_C2, myDegmax, mySegmax );
+ MkSw.SetForceApproxC1(myForceApproxC1);
+ MkSw.Build( myReversedEdges, myTapes,
+ BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
result = MkSw.Shape();
+
+ Handle(TopTools_HArray2OfShape) aSections = MkSw.Sections();
+
+ if (aSections.IsNull() == Standard_False) {
+ const Standard_Integer aVLast = aSections->UpperCol();
+
+ myFirst = aSections->Value(1, 1);
+ myLast = aSections->Value(1, aVLast);
+ }
}
if (TheS.ShapeType() == TopAbs_WIRE ) {
BRepFill_Sweep MkSw(Section, myLoc, Standard_True);
MkSw.SetBounds(TopoDS::Wire(TheFirst),
TopoDS::Wire(TheLast));
- MkSw.Build( BRepFill_Modified, GeomFill_Location, GeomAbs_C2, myDegmax, mySegmax );
+ MkSw.SetForceApproxC1(myForceApproxC1);
+ MkSw.Build( myReversedEdges, myTapes,
+ BRepFill_Modified, myContinuity, GeomFill_Location, myDegmax, mySegmax );
result = MkSw.Shape();
+ //Correct <myFirst> and <myLast>
+ ReverseModifiedEdges(myFirst, myReversedEdges);
+ ReverseModifiedEdges(myLast, myReversedEdges);
// Labeling of elements
if (mySections.IsNull()) {
Somme->SetValue(ii, jj, Aux->Value(kk, jj));
}
myFaces = Somme;
-
Aux = MkSw.Sections();
length = Aux->ColLength() + mySections->ColLength();
for (jj=1; jj<=mySections->RowLength(); jj++) {
for (ii=1; ii<=mySections->ColLength(); ii++)
Somme->SetValue(ii, jj, mySections->Value(ii, jj));
-
+
+ myCurIndexOfSectionEdge = mySections->ColLength()+1;
+
for (kk=1, ii=mySections->ColLength()+1;
kk <=Aux->ColLength(); kk++, ii++)
Somme->SetValue(ii, jj, Aux->Value(kk, jj));
kk <=Aux->ColLength(); kk++, ii++)
Somme->SetValue(ii, jj, Aux->Value(kk, jj));
}
- myEdges = Somme;
+
+ myEdges = Somme;
}
}
}
if ( TheS.ShapeType() == TopAbs_FACE ) {
Standard_Integer ii, jj;
+ //jgv
+ TopExp_Explorer Explo(result, TopAbs_FACE);
+ for (; Explo.More(); Explo.Next())
+ {
+ TopoDS_Shape aFace = Explo.Current();
+ RebuildTopOrBottomFace(aFace.Reversed(), Standard_True); //top face was reversed
+ }
+ /////
TopoDS_Face F;
for (ii=InitialLength+1; ii<=myFaces->ColLength(); ii++) {
for (jj=1; jj<=myFaces->RowLength(); jj++) {
if ( !mySpine.Closed()) {
// if Spine is not closed
// add the last face of the solid
+
+ //jgv
+ RebuildTopOrBottomFace(TheLast, Standard_False); //bottom face
+ /////
B.Add(result, TopoDS::Face(TheLast));
}
else {
return result;
}
- return result;
}
//============================================================================
if (mySegmax < RealSegmax)
mySegmax = RealSegmax;
}
+
+//=======================================================================
+//function : RebuildTopOrBottomFace
+//purpose : Correct orientation of v-iso edges
+// according to new 3d and 2d curves taken from swept surfaces
+//=======================================================================
+
+void BRepFill_Pipe::RebuildTopOrBottomFace(const TopoDS_Shape& aFace,
+ const Standard_Boolean IsTop) const
+{
+ Standard_Integer IndexOfSection =
+ (IsTop)? 1 : mySections->RowLength();
+
+ Standard_Integer ii;
+ BRep_Builder BB;
+ TopoDS_Iterator itf(aFace);
+ for (; itf.More(); itf.Next())
+ {
+ TopoDS_Shape aWire = itf.Value();
+ TopTools_SequenceOfShape InitEdges;
+ TopTools_SequenceOfShape ResEdges;
+ TopoDS_Iterator itw(aWire);
+ for (; itw.More(); itw.Next())
+ {
+ TopoDS_Shape anEdge = itw.Value();
+ for (ii = myCurIndexOfSectionEdge; ii <= mySections->ColLength(); ii++)
+ {
+ TopoDS_Shape aVisoEdge = mySections->Value(ii, IndexOfSection);
+ if (anEdge.IsSame(aVisoEdge))
+ {
+ InitEdges.Append(anEdge);
+ ResEdges.Append(aVisoEdge);
+ break;
+ }
+ }
+ }
+ aWire.Free(Standard_True);
+ for (ii = 1; ii <= InitEdges.Length(); ii++)
+ {
+ BB.Remove(aWire, InitEdges(ii));
+ UpdateTolFromTopOrBottomPCurve(TopoDS::Face(aFace), TopoDS::Edge(ResEdges(ii)));
+ BB.Add(aWire, ResEdges(ii));
+ }
+ }
+}