1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-19 13:40:49 +03:00

Integration of OCCT 6.5.0 from SVN

This commit is contained in:
bugmaster
2011-03-16 07:30:28 +00:00
committed by bugmaster
parent 4903637061
commit 7fd59977df
16375 changed files with 3882564 additions and 0 deletions

321
src/GeomFill/GeomFill.cdl Executable file
View File

@@ -0,0 +1,321 @@
-- File: GeomFill.cdl
-- Created: Tue Sep 28 11:34:33 1993
-- Author: Bruno DUMORTIER
-- <dub@sdsun1>
---Copyright: Matra Datavision 1993
---Purpose: Tools and Data to filling Surface and Sweep Surfaces
package GeomFill
uses
TColgp,
TColGeom,
TColGeom2d,
TColStd,
TCollection,
gp,
Geom,
Geom2d,
GeomAbs,
Convert,
Adaptor3d,
GeomAdaptor,
Law,
Extrema,
AppBlend,
Approx,
math,
MMgt,
StdFail
is
enumeration FillingStyle
is StretchStyle, CoonsStyle, CurvedStyle end;
---Purpose: Defines the three filling styles used in this package
-- - GeomFill_Stretch - the style with the flattest patches
-- - GeomFill_Coons - a rounded style of patch with
-- less depth than those of Curved
-- - GeomFill_Curved - the style with the most rounded patches.
enumeration ApproxStyle
is Section, Location end;
enumeration PipeError
is PipeOk,
PipeNotOk,
PlaneNotIntersectGuide,
ImpossibleContact
end;
enumeration Trihedron
is IsCorrectedFrenet, IsFixed, IsFrenet, IsConstantNormal, IsDarboux,
IsGuideAC, IsGuidePlan,
IsGuideACWithContact, IsGuidePlanWithContact end;
class Filling;
---Purpose: Root class for Filling;
class Stretch;
class Coons;
class Curved;
class BezierCurves;
---Purpose: class for Filling BezierCurves.
-- WARNING:
-- Some problems may appear with the rational Curves.
class BSplineCurves;
---Purpose: class for Filling BSplineCurves.
-- WARNING:
-- Some problems may appear with the rational Curves.
class Profiler;
---Purpose: class for evaluation of the Common BSpline Profile
-- from a sequence a BSplineCurves.
class SectionGenerator;
---Purpose: class for instantiation of AppBlend .
-- inherits Profiler.
class Line;
---Purpose: class for instantiation of AppBlend
class AppSurf instantiates AppSurf from AppBlend
( SectionGenerator from GeomFill,
Line from GeomFill);
---Purpose: Approximate a BSplineSurface passing by all the
-- curves described in the SectionGenerator
class SweepSectionGenerator;
---Purpose: class for instantiation of AppBlend.
-- evaluate the sections of a sweep surface.
class AppSweep instantiates AppSurf from AppBlend
( SweepSectionGenerator from GeomFill,
Line from GeomFill);
---Purpose: Approximate a sweep surface passing by all the
-- curves described in the SweepSectionGenerator.
class Generator;
---Purpose: Create a surface using generating lines. Inherits
-- profiler. The surface will be a BSplineSurface
-- passing by all the curves described in the
-- generator. The VDegree of the resulting surface is
-- 1.
class Pipe;
---Purpose: Create a pipe surface.
--- Family of classes providing algorithms to fill a contour with
-- constraints of tangency.
-- class Draft;
---Purpose: Depouille
class Tensor;
class ConstrainedFilling;
---Purpose: class for filling a contour of 2, 3 or 4 curves with
-- tangency constaints. The only FillingStyle used is
-- Coons.
--
deferred class Boundary; -- inherits TShared
---Purpose: Root class defining the methods we need to make a
-- constrained boundary. Any new type of constrained
-- boundary must inherit this class.
--
class DegeneratedBound; -- inherits Boundary
---Purpose: class defining a degenerated boundary for a
-- constrained filling with a point and no other
-- constraint. Only used to simulate an ordinary bound,
-- may not be usefull and desapear soon.
--
class SimpleBound; -- inherits Boundary
---Purpose: class defining a boundary for a constrained filling
-- with a 3d curve and no other constraint. Contains
-- fields to allow a reparametrization of curve.
--
class BoundWithSurf; -- inherits Boundary
---Purpose: class defining a boundary for a constrained filling
-- with a curve and a normals field along a surface.
-- Contains fields to allow a reparametrization of curve
-- and normals field.
--
class CoonsAlgPatch; -- inherits TShared
---Purpose: class defining an algorithmic patch based on 4 Curves.
deferred class TgtField; -- inherits TShared
---Purpose: Root class defining the methods we need to definine an
-- algorithmic tgte field.
class TgtOnCoons; -- inherits TgteField
---Purpose: Class defining an algorithmic tgte field along a
-- boundary of a CoonsAlgPatch.
class CornerState;
---Purpose: Class (should be a structure) storing the informations
-- about continuity, normals parallelism, coons
-- conditions and bounds tangents angle on the corner of
-- contour to be filled.
--
-- instantiation of Sequence of Trsf
--
class SequenceOfTrsf
instantiates Sequence from TCollection (Trsf from gp);
--
-- private classes
--
private class CircularBlendFunc;
private class SweepFunction;
private class LocFunction;
private class PolynomialConvertor;
private class QuasiAngularConvertor;
private class SnglrFunc;
private class FunctionDraft;
private class PlanFunc;
private class FunctionGuide;
---
--- Sweep Data
---
deferred class SectionLaw;
class UniformSection;
class EvolvedSection;
class NSections;
deferred class LocationLaw;
class CurveAndTrihedron;
class LocationDraft;
class LocationGuide;
deferred class TrihedronLaw;
class Fixed;
class Frenet;
class CorrectedFrenet;
class ConstantBiNormal;
class Darboux;
class DraftTrihedron;
deferred class TrihedronWithGuide;
class GuideTrihedronAC;
class GuideTrihedronPlan;
class Sweep;
class SectionPlacement;
class Array1OfSectionLaw
instantiates Array1 from TCollection (SectionLaw from GeomFill);
class HArray1OfSectionLaw
instantiates HArray1 from TCollection (SectionLaw from GeomFill,
Array1OfSectionLaw from GeomFill);
class Array1OfLocationLaw
instantiates Array1 from TCollection (LocationLaw from GeomFill);
class HArray1OfLocationLaw
instantiates HArray1 from TCollection (LocationLaw from GeomFill,
Array1OfLocationLaw from GeomFill);
-- package methods
--
Surface( Curve1 : Curve from Geom;
Curve2 : Curve from Geom)
returns Surface from Geom;
---Purpose:
-- Builds a ruled surface between the two curves, Curve1 and Curve2.
GetCircle(TConv : ParameterisationType from Convert;
ns1, ns2 : Vec from gp;
nplan : Vec from gp;
pt1, pt2 : Pnt from gp;
Rayon : Real from Standard;
Center : Pnt from gp;
Poles : out Array1OfPnt from TColgp;
Weigths : out Array1OfReal from TColStd);
GetCircle(TConv : ParameterisationType from Convert;
ns1, ns2 : Vec from gp;
dn1w, dn2w : Vec from gp;
nplan, dnplan : Vec from gp;
pts1, pts2 : Pnt from gp;
tang1, tang2 : Vec from gp;
Rayon, DRayon : Real from Standard;
Center : Pnt from gp;
DCenter : Vec from gp;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
Weigths : out Array1OfReal from TColStd;
DWeigths : out Array1OfReal from TColStd)
---Level: Internal
returns Boolean;
GetCircle(TConv : ParameterisationType from Convert;
ns1, ns2 : Vec from gp;
dn1w, dn2w : Vec from gp;
d2n1w, d2n2w : Vec from gp;
nplan, dnplan, d2nplan : Vec from gp;
pts1 , pts2 : Pnt from gp;
tang1 , tang2 : Vec from gp;
Dtang1, Dtang2 : Vec from gp;
Rayon, DRayon, D2Rayon : Real from Standard;
Center : Pnt from gp;
DCenter, D2Center : Vec from gp;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
D2Poles : out Array1OfVec from TColgp;
Weigths : out Array1OfReal from TColStd;
DWeigths : out Array1OfReal from TColStd;
D2Weigths : out Array1OfReal from TColStd)
---Level: Internal
returns Boolean;
GetShape(MaxAng: Real from Standard;
NbPoles,NbKnots,Degree : out Integer from Standard;
TypeConv : in out ParameterisationType from Convert);
Knots(TypeConv : ParameterisationType from Convert;
TKnots: out Array1OfReal from TColStd);
Mults(TypeConv : ParameterisationType from Convert;
TMults: out Array1OfInteger from TColStd);
GetMinimalWeights(TConv : ParameterisationType from Convert;
AngleMin : Real;
AngleMax : Real;
Weigths : out Array1OfReal from TColStd);
GetTolerance(TConv : ParameterisationType from Convert;
AngleMin : Real;
Radius : Real;
AngularTol : Real;
SpatialTol : Real)
---Purpose: Used by the generical classes to determine
-- Tolerance for approximation
---Level: Internal
returns Real;
end GeomFill;

750
src/GeomFill/GeomFill.cxx Executable file
View File

@@ -0,0 +1,750 @@
// File: GeomFill.cxx
// Created: Fri Feb 25 09:49:20 1994
// Author: Bruno DUMORTIER
// <dub@fuegox>
#include <GeomFill.ixx>
#include <GeomFill_Generator.hxx>
#include <Geom_RectangularTrimmedSurface.hxx>
#include <Geom_CylindricalSurface.hxx>
#include <Geom_ConicalSurface.hxx>
#include <Geom_Plane.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_Line.hxx>
#include <Geom_Circle.hxx>
#include <gp_Lin.hxx>
#include <gp_Circ.hxx>
#include <gp_Dir.hxx>
#include <gp_Ax3.hxx>
#include <gp_Vec.hxx>
#include <GeomConvert.hxx>
#include <GeomFill_PolynomialConvertor.hxx>
#include <GeomFill_QuasiAngularConvertor.hxx>
#include <Precision.hxx>
#include <Standard_Static.hxx>
// La classe de convertion
Standard_STATIC (GeomFill_PolynomialConvertor, PConvertor);
Standard_STATIC (GeomFill_QuasiAngularConvertor, QConvertor);
//=======================================================================
//function : Surface
//purpose :
//=======================================================================
Handle(Geom_Surface) GeomFill::Surface
(const Handle(Geom_Curve)& Curve1,
const Handle(Geom_Curve)& Curve2)
{
Handle(Geom_Curve) TheCurve1, TheCurve2;
Handle(Geom_Surface) Surf;
// recherche du type de la surface resultat:
// les surfaces reglees particulieres sont :
// - les plans
// - les cylindres
// - les cones
// dans ces trois cas les courbes doivent etre de meme type :
// - ou 2 droites
// - ou 2 cercles
Standard_Real a1=0, a2=0, b1=0, b2=0;
Standard_Boolean Trim1= Standard_False, Trim2 = Standard_False;
if ( Curve1->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
Handle(Geom_TrimmedCurve) Ctrim
= Handle(Geom_TrimmedCurve)::DownCast(Curve1);
TheCurve1 = Ctrim->BasisCurve();
a1 = Ctrim->FirstParameter();
b1 = Ctrim->LastParameter();
Trim1 = Standard_True;
}
else {
TheCurve1 = Handle(Geom_Curve)::DownCast(Curve1->Copy());
}
if ( Curve2->IsKind(STANDARD_TYPE(Geom_TrimmedCurve))) {
Handle(Geom_TrimmedCurve) Ctrim
= Handle(Geom_TrimmedCurve)::DownCast(Curve2);
TheCurve2 = Ctrim->BasisCurve();
a2 = Ctrim->FirstParameter();
b2 = Ctrim->LastParameter();
Trim2 = Standard_True;
}
else {
TheCurve2 = Handle(Geom_Curve)::DownCast(Curve2->Copy());
}
Standard_Boolean IsDone = Standard_False;
// Les deux courbes sont des droites.
if ( TheCurve1->IsKind(STANDARD_TYPE(Geom_Line)) &&
TheCurve2->IsKind(STANDARD_TYPE(Geom_Line)) &&
Trim1 && Trim2 ) {
gp_Lin L1 = (Handle(Geom_Line)::DownCast(TheCurve1))->Lin();
gp_Lin L2 = (Handle(Geom_Line)::DownCast(TheCurve2))->Lin();
gp_Dir D1 = L1.Direction();
gp_Dir D2 = L2.Direction();
if ( D1.IsParallel(D2, Precision::Angular())) {
gp_Vec P1P2(L1.Location(),L2.Location());
Standard_Real proj = P1P2.Dot(D1);
if ( D1.IsEqual(D2, Precision::Angular())) {
if ( Abs( a1 - proj - a2 ) <= Precision::Confusion() &&
Abs( b1 - proj - b2 ) <= Precision::Confusion() ) {
gp_Ax3 Ax(L1.Location(), gp_Dir(D1.Crossed(P1P2)),D1);
Handle(Geom_Plane) P = new Geom_Plane(Ax);
Standard_Real V = P1P2.Dot( Ax.YDirection());
Surf = new Geom_RectangularTrimmedSurface( P , a1, b1,
Min(0.,V),Max(0.,V));
IsDone = Standard_True;
}
}
if ( D1.IsOpposite(D2, Precision::Angular())) {
if ( Abs( a1 - proj + b2 ) <= Precision::Confusion() &&
Abs( b1 - proj + a2 ) <= Precision::Confusion() ) {
gp_Ax3 Ax(L1.Location(), gp_Dir(D1.Crossed(P1P2)),D1);
Handle(Geom_Plane) P = new Geom_Plane(Ax);
Standard_Real V = P1P2.Dot( Ax.YDirection());
Surf = new Geom_RectangularTrimmedSurface( P , a1, b1,
Min(0.,V),Max(0.,V));
IsDone = Standard_True;
}
}
}
}
// Les deux courbes sont des cercles.
else if ( TheCurve1->IsKind(STANDARD_TYPE(Geom_Circle)) &&
TheCurve2->IsKind(STANDARD_TYPE(Geom_Circle)) ) {
gp_Circ C1 = (Handle(Geom_Circle)::DownCast(TheCurve1))->Circ();
gp_Circ C2 = (Handle(Geom_Circle)::DownCast(TheCurve2))->Circ();
gp_Ax3 A1 = C1.Position();
gp_Ax3 A2 = C2.Position();
// first, A1 & A2 must be coaxials
if ( A1.Axis().IsCoaxial(A2.Axis(),Precision::Angular(),
Precision::Confusion()) ) {
Standard_Real V =
gp_Vec( A1.Location(),A2.Location()).Dot(gp_Vec(A1.Direction()));
if ( !Trim1 && !Trim2) {
if ( Abs( C1.Radius() - C2.Radius()) < Precision::Confusion()) {
Handle(Geom_CylindricalSurface) C =
new Geom_CylindricalSurface( A1, C1.Radius());
Surf = new Geom_RectangularTrimmedSurface
( C, Min(0.,V), Max(0.,V), Standard_False);
}
else {
Standard_Real Rad = C2.Radius() - C1.Radius();
Standard_Real Ang = ATan( Rad / V);
if ( Ang < 0.) {
A1.ZReverse();
V = -V;
Ang = -Ang;
}
Handle(Geom_ConicalSurface) C =
new Geom_ConicalSurface( A1, Ang, C1.Radius());
V /= Cos(Ang);
Surf = new Geom_RectangularTrimmedSurface
( C, Min(0.,V), Max(0.,V), Standard_False);
}
IsDone = Standard_True;
}
else if ( Trim1 && Trim2) {
}
}
}
if ( !IsDone) {
GeomFill_Generator Generator;
Generator.AddCurve(Curve1);
Generator.AddCurve(Curve2);
Generator.Perform(Precision::PConfusion());
Surf = Generator.Surface();
}
return Surf;
}
//=======================================================================
//function : GetShape
//purpose :
//=======================================================================
void GeomFill::GetShape (const Standard_Real MaxAng,
Standard_Integer& NbPoles,
Standard_Integer& NbKnots,
Standard_Integer& Degree,
Convert_ParameterisationType& TConv)
{
switch (TConv) {
case Convert_QuasiAngular:
{
NbPoles = 7 ;
NbKnots = 2 ;
Degree = 6 ;
}
break;
case Convert_Polynomial:
{
NbPoles = 8;
NbKnots = 2;
Degree = 7;
}
break;
default:
{
Standard_Integer NbSpan =
(Standard_Integer)(Ceiling(3.*Abs(MaxAng)/2./PI));
NbPoles = 2*NbSpan+1;
NbKnots = NbSpan+1;
Degree = 2;
if (NbSpan == 1) {
TConv = Convert_TgtThetaOver2_1;
}
else if (NbSpan == 2) {
TConv = Convert_TgtThetaOver2_2;
}
else if (NbSpan == 3) {
TConv = Convert_TgtThetaOver2_3;
}
}
}
}
//=======================================================================
//function : GetMinimalWeights
//purpose : On suppose les extremum de poids sont obtenus pour les
// extremums d'angles (A verifier eventuelement pour Quasi-Angular)
//=======================================================================
void GeomFill::GetMinimalWeights(const Convert_ParameterisationType TConv,
const Standard_Real MinAng,
const Standard_Real MaxAng,
TColStd_Array1OfReal& Weights)
{
if (TConv == Convert_Polynomial) Weights.Init(1);
else {
gp_Ax2 popAx2(gp_Pnt(0, 0, 0), gp_Dir(0,0,1));
gp_Circ C (popAx2, 1);
Handle(Geom_TrimmedCurve) Sect1 =
new Geom_TrimmedCurve(new Geom_Circle(C), 0., MaxAng);
Handle(Geom_BSplineCurve) CtoBspl =
GeomConvert::CurveToBSplineCurve(Sect1, TConv);
CtoBspl->Weights(Weights);
TColStd_Array1OfReal poids (Weights.Lower(), Weights.Upper());
Standard_Real angle_min = Max(Precision::PConfusion(), MinAng);
Handle(Geom_TrimmedCurve) Sect2 =
new Geom_TrimmedCurve(new Geom_Circle(C), 0., angle_min);
CtoBspl = GeomConvert::CurveToBSplineCurve(Sect2, TConv);
CtoBspl->Weights(poids);
for (Standard_Integer ii=Weights.Lower(); ii<=Weights.Upper(); ii++) {
if (poids(ii) < Weights(ii)) {
Weights(ii) = poids(ii);
}
}
}
}
//=======================================================================
//function : Knots
//purpose :
//=======================================================================
void GeomFill::Knots(const Convert_ParameterisationType TConv,
TColStd_Array1OfReal& TKnots)
{
if ((TConv!=Convert_QuasiAngular) &&
(TConv!=Convert_Polynomial) ) {
Standard_Integer i;
Standard_Real val = 0.;
for (i=TKnots.Lower(); i<=TKnots.Upper(); i++) {
TKnots(i) = val;
val = val+1.;
}
}
else {
TKnots(1) = 0.;
TKnots(2) = 1.;
}
}
//=======================================================================
//function : Mults
//purpose :
//=======================================================================
void GeomFill::Mults(const Convert_ParameterisationType TConv,
TColStd_Array1OfInteger& TMults)
{
switch (TConv) {
case Convert_QuasiAngular :
{
TMults(1) = 7;
TMults(2) = 7;
}
break;
case Convert_Polynomial :
{
TMults(1) = 8;
TMults(2) = 8;
}
break;
default :
{
// Cas rational classsique
Standard_Integer i;
TMults(TMults.Lower())=3;
for (i=TMults.Lower()+1; i<=TMults.Upper()-1; i++) {
TMults(i) = 2;
}
TMults(TMults.Upper())=3;
}
}
}
//=======================================================================
//function : GetTolerance
//purpose : Determiner la Tolerance 3d permetant de respecter la Tolerance
// de continuite G1.
//=======================================================================
Standard_Real GeomFill::GetTolerance(const Convert_ParameterisationType TConv,
const Standard_Real AngleMin,
const Standard_Real Radius,
const Standard_Real AngularTol,
const Standard_Real SpatialTol)
{
gp_Ax2 popAx2(gp_Pnt(0, 0, 0), gp_Dir(0,0,1));
gp_Circ C (popAx2, Radius);
Handle(Geom_Circle) popCircle = new Geom_Circle(C);
Handle(Geom_TrimmedCurve) Sect =
new Geom_TrimmedCurve(popCircle ,
0.,Max(AngleMin, 0.02) );
// 0.02 est proche d'1 degree, en desous on ne se preocupe pas de la tngence
// afin d'eviter des tolerances d'approximation tendant vers 0 !
Handle(Geom_BSplineCurve) CtoBspl =
GeomConvert::CurveToBSplineCurve(Sect, TConv);
Standard_Real Dist;
Dist = CtoBspl->Pole(1).Distance(CtoBspl->Pole(2)) + SpatialTol;
return Dist*AngularTol/2;
}
//===========================================================================
//function : GetCircle
//purpose : Calculs les poles et poids d'un cercle definie par ses extremites
// et son rayon.
// On evite (si possible) de passer par les convertions pour
// 1) Des problemes de performances.
// 2) Assurer la coherance entre cette methode est celle qui donne la derive
//============================================================================
void GeomFill::GetCircle( const Convert_ParameterisationType TConv,
const gp_Vec& ns1, // Normal rentrente au premier point
const gp_Vec& ns2, // Normal rentrente au second point
const gp_Vec& nplan, // Normal au plan
const gp_Pnt& pts1,
const gp_Pnt& pts2,
const Standard_Real Rayon, // Rayon (doit etre positif)
const gp_Pnt& Center,
TColgp_Array1OfPnt& Poles,
TColStd_Array1OfReal& Weights)
{
// La classe de convertion
Standard_Integer i, jj;
Standard_Real Cosa,Sina,Angle,Alpha,Cosas2,lambda;
gp_Vec temp, np2;
Standard_Integer low = Poles.Lower();
Standard_Integer upp = Poles.Upper();
Cosa = ns1.Dot(ns2);
Sina = nplan.Dot(ns1.Crossed(ns2));
if (Cosa<-1.) {Cosa=-1; Sina = 0;}
if (Cosa>1.) {Cosa=1; Sina = 0;}
Angle = ACos(Cosa);
// Recadrage sur ]-pi/2, 3pi/2]
if (Sina <0.) {
if (Cosa > 0.) Angle = -Angle;
else Angle = 2.*PI - Angle;
}
switch (TConv) {
case Convert_QuasiAngular:
{ // On utilise le bon "Convertor"
if (!QConvertor().Initialized()) QConvertor().Init();
QConvertor().Section(pts1, Center, nplan, Angle, Poles, Weights);
break;
}
case Convert_Polynomial:
{ // On utilise le bon "Convertor"
if (!PConvertor().Initialized()) PConvertor().Init();
PConvertor().Section(pts1, Center, nplan, Angle, Poles);
Weights.Init(1);
break;
}
default:
{
// Cas Rational, on utilise une expression directe beaucoup plus
// performente que GeomConvert
Standard_Integer NbSpan=(Poles.Length()-1)/2;
Poles(low) = pts1;
Poles(upp) = pts2;
Weights(low) = 1;
Weights(upp) = 1;
np2 = nplan.Crossed(ns1);
Alpha = Angle/((Standard_Real)(NbSpan));
Cosas2 = Cos(Alpha/2);
for (i=1, jj=low+2; i<= NbSpan-1; i++, jj+=2) {
lambda = ((Standard_Real)(i))*Alpha;
Cosa = Cos(lambda);
Sina = Sin(lambda);
temp.SetLinearForm(Cosa-1, ns1, Sina, np2);
Poles(jj).SetXYZ(pts1.XYZ() + Rayon*temp.XYZ());
Weights(jj) = 1;
}
lambda = 1./(2.*Cosas2*Cosas2);
for (i=1, jj=low+1; i<=NbSpan; i++, jj+=2) {
temp.SetXYZ(Poles(jj-1).XYZ() + Poles(jj+1).XYZ()
-2.*Center.XYZ());
Poles(jj).SetXYZ(Center.XYZ() + lambda*temp.XYZ());
Weights(jj) = Cosas2;
}
}
}
}
Standard_Boolean GeomFill::GetCircle(const Convert_ParameterisationType TConv,
const gp_Vec& ns1, const gp_Vec& ns2,
const gp_Vec& dn1w, const gp_Vec& dn2w,
const gp_Vec& nplan, const gp_Vec& dnplan,
const gp_Pnt& pts1, const gp_Pnt& pts2,
const gp_Vec& tang1, const gp_Vec& tang2,
const Standard_Real Rayon,
const Standard_Real DRayon,
const gp_Pnt& Center,
const gp_Vec& DCenter,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfVec& DPoles,
TColStd_Array1OfReal& Weights,
TColStd_Array1OfReal& DWeights)
{
Standard_Real Cosa,Sina,Cosas2,Sinas2,Angle,DAngle,Alpha,lambda,Dlambda;
gp_Vec temp, np2, dnp2;
Standard_Integer i, jj;
Standard_Integer NbSpan=(Poles.Length()-1)/2;
Standard_Integer low = Poles.Lower();
Standard_Integer upp = Poles.Upper();
Cosa = ns1.Dot(ns2);
Sina = nplan.Dot(ns1.Crossed(ns2));
if (Cosa<-1.){Cosa=-1; Sina = 0;}
if (Cosa>1.) {Cosa=1; Sina = 0;}
Angle = ACos(Cosa);
// Recadrage sur ]-pi/2, 3pi/2]
if (Sina <0.) {
if (Cosa > 0.) Angle = -Angle;
else Angle = 2.*PI - Angle;
}
if (Abs(Sina)>Abs(Cosa)) {
DAngle = -(dn1w.Dot(ns2) + ns1.Dot(dn2w))/Sina;
}
else{
DAngle = (dnplan.Dot(ns1.Crossed(ns2)) + nplan.Dot(dn1w.Crossed(ns2)
+ ns1.Crossed(dn2w)))/Cosa;
}
// Aux Extremites.
Poles(low) = pts1;
Poles(upp) = pts2;
Weights(low) = 1;
Weights(upp) = 1;
DPoles(low) = tang1;
DPoles(upp) = tang2;
DWeights(low) = 0;
DWeights(upp) = 0;
switch (TConv) {
case Convert_QuasiAngular:
{
if (!QConvertor().Initialized()) QConvertor().Init();
QConvertor().Section(pts1, tang1,
Center, DCenter,
nplan, dnplan,
Angle, DAngle,
Poles, DPoles,
Weights, DWeights);
return Standard_True;
}
case Convert_Polynomial:
{
if (!PConvertor().Initialized()) PConvertor().Init();
PConvertor().Section(pts1, tang1,
Center, DCenter,
nplan, dnplan,
Angle, DAngle,
Poles, DPoles);
Weights.Init(1);
DWeights.Init(0);
return Standard_True;
}
default:
// Cas rationel classique
{
np2 = nplan.Crossed(ns1);
dnp2 = dnplan.Crossed(ns1).Added(nplan.Crossed(dn1w));
Alpha = Angle/((Standard_Real)(NbSpan));
Cosas2 = Cos(Alpha/2);
Sinas2 = Sin(Alpha/2);
for (i=1, jj=low+2; i<= NbSpan-1; i++, jj+=2) {
lambda = ((Standard_Real)(i))*Alpha;
Cosa = Cos(lambda);
Sina = Sin(lambda);
temp.SetLinearForm(Cosa-1,ns1,Sina,np2);
Poles(jj).SetXYZ(pts1.XYZ() + Rayon*temp.XYZ());
DPoles(jj).SetLinearForm(DRayon, temp, tang1);
temp.SetLinearForm(-Sina,ns1,Cosa,np2);
temp.Multiply(((Standard_Real)(i))/((Standard_Real)(NbSpan))*DAngle);
temp.Add(((Cosa-1)*dn1w).Added(Sina*dnp2));
DPoles(jj)+= Rayon*temp;
}
lambda = 1./(2.*Cosas2*Cosas2);
Dlambda = (lambda*Sinas2*DAngle)/(Cosas2*NbSpan);
for (i=1, jj=low; i<=NbSpan; i++, jj+=2) {
temp.SetXYZ(Poles(jj).XYZ() + Poles(jj+2).XYZ()
-2.*Center.XYZ());
Poles(jj+1).SetXYZ(Center.XYZ()+lambda*temp.XYZ());
DPoles(jj+1).SetLinearForm(Dlambda, temp,
1.-2*lambda, DCenter,
lambda, (DPoles(jj)+ DPoles(jj+2)));
}
// Les poids
Dlambda = -Sinas2*DAngle/(2*NbSpan);
for (i=low; i<upp; i+=2) {
Weights(i) = 1.;
Weights(i+1) = Cosas2;
DWeights(i) = 0.;
DWeights(i+1) = Dlambda;
}
}
return Standard_True;
}
return Standard_False;
}
Standard_Boolean GeomFill::GetCircle(const Convert_ParameterisationType TConv,
const gp_Vec& ns1, const gp_Vec& ns2,
const gp_Vec& dn1w, const gp_Vec& dn2w,
const gp_Vec& d2n1w, const gp_Vec& d2n2w,
const gp_Vec& nplan, const gp_Vec& dnplan,
const gp_Vec& d2nplan,
const gp_Pnt& pts1, const gp_Pnt& pts2,
const gp_Vec& tang1, const gp_Vec& tang2,
const gp_Vec& Dtang1, const gp_Vec& Dtang2,
const Standard_Real Rayon,
const Standard_Real DRayon,
const Standard_Real D2Rayon,
const gp_Pnt& Center,
const gp_Vec& DCenter,
const gp_Vec& D2Center,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfVec& DPoles,
TColgp_Array1OfVec& D2Poles,
TColStd_Array1OfReal& Weights,
TColStd_Array1OfReal& DWeights,
TColStd_Array1OfReal& D2Weights)
{
Standard_Real Cosa,Sina,Cosas2,Sinas2;
Standard_Real Angle, DAngle, D2Angle, Alpha;
Standard_Real lambda, Dlambda, D2lambda, aux;
gp_Vec temp, dtemp, np2, dnp2, d2np2;
Standard_Integer i, jj;
Standard_Integer NbSpan=(Poles.Length()-1)/2;
Standard_Integer low = Poles.Lower();
Standard_Integer upp = Poles.Upper();
Cosa = ns1.Dot(ns2);
Sina = nplan.Dot(ns1.Crossed(ns2));
if (Cosa<-1.){Cosa=-1; Sina = 0;}
if (Cosa>1.) {Cosa=1; Sina = 0;}
Angle = ACos(Cosa);
// Recadrage sur ]-pi/2, 3pi/2]
if (Sina <0.) {
if (Cosa > 0.) Angle = -Angle;
else Angle = 2.*PI - Angle;
}
if (Abs(Sina)>Abs(Cosa)) {
aux = dn1w.Dot(ns2) + ns1.Dot(dn2w);
DAngle = -aux/Sina;
D2Angle = -(d2n1w.Dot(ns2) + 2*dn1w.Dot(dn2w) + ns1.Dot(d2n2w))/Sina
+ aux*(dnplan.Dot(ns1.Crossed(ns2)) + nplan.Dot(dn1w.Crossed(ns2)
+ ns1.Crossed(dn2w)))/(Sina*Sina);
}
else{
temp = dn1w.Crossed(ns2) + ns1.Crossed(dn2w);
DAngle = (dnplan.Dot(ns1.Crossed(ns2)) + nplan.Dot(temp))/Cosa;
D2Angle = ( d2nplan.Dot(ns1.Crossed(ns2)) +2*dnplan.Dot(temp)
+ nplan.Dot(d2n1w.Crossed(ns2) + 2*dn1w.Crossed(dn2w)
+ ns1.Crossed(d2n2w)) )/Cosa
- ( dn1w.Dot(ns2) + ns1.Dot(dn2w))
* (dnplan.Dot(ns1.Crossed(ns2)) + nplan.Dot(temp)) /(Cosa*Cosa);
}
// Aux Extremites.
Poles(low) = pts1;
Poles(upp) = pts2;
Weights(low) = 1;
Weights(upp) = 1;
DPoles(low) = tang1;
DPoles(upp) = tang2;
DWeights(low) = 0;
DWeights(upp) = 0;
D2Poles(low) = Dtang1;
D2Poles(upp) = Dtang2;
D2Weights(low) = 0;
D2Weights(upp) = 0;
switch (TConv) {
case Convert_QuasiAngular:
{
if (!QConvertor().Initialized()) QConvertor().Init();
QConvertor().Section(pts1, tang1, Dtang1,
Center, DCenter, D2Center,
nplan, dnplan, d2nplan,
Angle, DAngle, D2Angle,
Poles, DPoles, D2Poles,
Weights, DWeights, D2Weights);
return Standard_True;
}
case Convert_Polynomial:
{
if (!PConvertor().Initialized()) PConvertor().Init();
PConvertor().Section(pts1, tang1, Dtang1,
Center, DCenter, D2Center,
nplan, dnplan, d2nplan,
Angle, DAngle, D2Angle,
Poles, DPoles, D2Poles);
Weights.Init(1);
DWeights.Init(0);
D2Weights.Init(0);
return Standard_True;
}
default:
{
np2 = nplan.Crossed(ns1);
dnp2 = dnplan.Crossed(ns1).Added(nplan.Crossed(dn1w));
d2np2 = d2nplan.Crossed(ns1).Added(nplan.Crossed(dn2w));
d2np2 += 2*dnplan.Crossed(dn1w);
Alpha = Angle/((Standard_Real)(NbSpan));
Cosas2 = Cos(Alpha/2);
Sinas2 = Sin(Alpha/2);
for (i=1, jj=low+2; i<= NbSpan-1; i++, jj+=2) {
lambda = ((Standard_Real)(i))*Alpha;
Cosa = Cos(lambda);
Sina = Sin(lambda);
temp.SetLinearForm(Cosa-1,ns1,Sina,np2);
Poles(jj).SetXYZ(pts1.XYZ() + Rayon*temp.XYZ());
DPoles(jj).SetLinearForm(DRayon, temp, tang1);
dtemp.SetLinearForm(-Sina,ns1,Cosa,np2);
aux = ((Standard_Real)(i))/((Standard_Real)(NbSpan));
dtemp.Multiply(aux*DAngle);
dtemp.Add(((Cosa-1)*dn1w).Added(Sina*dnp2));
DPoles(jj)+= Rayon*dtemp;
D2Poles(jj).SetLinearForm(D2Rayon, temp,
2*DRayon, dtemp, Dtang1);
temp.SetLinearForm(Cosa-1, dn2w, Sina, d2np2);
dtemp.SetLinearForm(-Sina,ns1,Cosa,np2);
temp+= (aux*aux*D2Angle)*dtemp;
dtemp.SetLinearForm(-Sina, dn1w+np2, Cosa, dnp2,
-Cosa, ns1);
temp+=(aux*DAngle)*dtemp;
D2Poles(jj)+= Rayon*temp;
}
lambda = 1./(2.*Cosas2*Cosas2);
Dlambda = (lambda*Sinas2*DAngle)/(Cosas2*NbSpan);
aux = Sinas2/Cosas2;
D2lambda = ( Dlambda * aux*DAngle
+ D2Angle * aux*lambda
+ (1+aux*aux)*(DAngle/(2*NbSpan)) * DAngle*lambda )
/ NbSpan;
for (i=1, jj=low; i<=NbSpan; i++, jj+=2) {
temp.SetXYZ(Poles(jj).XYZ() + Poles(jj+2).XYZ()
-2.*Center.XYZ());
Poles(jj+1).SetXYZ(Center.XYZ()+lambda*temp.XYZ());
dtemp.SetXYZ(DPoles(jj).XYZ() + DPoles(jj+2).XYZ()
-2.*DCenter.XYZ());
DPoles(jj+1).SetLinearForm(Dlambda, temp,
lambda, dtemp,
DCenter);
D2Poles(jj+1).SetLinearForm(D2lambda, temp,
2*Dlambda, dtemp,
lambda, (D2Poles(jj)+ D2Poles(jj+2)));
D2Poles(jj+1)+= (1-2*lambda)*D2Center;
}
// Les poids
Dlambda = -Sinas2*DAngle/(2*NbSpan);
D2lambda = -Sinas2*D2Angle/(2*NbSpan)
-Cosas2*Pow(DAngle/(2*NbSpan),2);
for (i=low; i<upp; i+=2) {
Weights(i) = 1.;
Weights(i+1) = Cosas2;
DWeights(i) = 0.;
DWeights(i+1) = Dlambda;
D2Weights(i) = 0.;
D2Weights(i+1) = D2lambda;
}
}
return Standard_True;
}
return Standard_False;
}

View File

@@ -0,0 +1,100 @@
-- File: GeomFill_BSplineCurves.cdl
-- Created: Wed Oct 6 10:50:12 1993
-- Author: Bruno DUMORTIER
-- <dub@sdsun1>
---Copyright: Matra Datavision 1993
class BSplineCurves from GeomFill
---Purpose: An algorithm for constructing a BSpline surface filled
-- from contiguous BSpline curves which form its boundaries.
-- The algorithm accepts two, three or four BSpline
-- curves as the boundaries of the target surface.
-- A range of filling styles - more or less rounded, more
-- or less flat - is available.
-- A BSplineCurves object provides a framework for:
-- - defining the boundaries, and the filling style of the surface
-- - implementing the construction algorithm
-- - consulting the result.
-- Warning
-- Some problems may show up with rational curves.
uses
BSplineCurve from Geom,
BSplineSurface from Geom,
FillingStyle from GeomFill
raises
ConstructionError from Standard
is
Create;
---Purpose: Constructs a default BSpline surface framework.
Create( C1, C2, C3, C4 : BSplineCurve from Geom;
Type : FillingStyle from GeomFill)
returns BSplineCurves from GeomFill;
Create( C1, C2, C3 : BSplineCurve from Geom;
Type : FillingStyle from GeomFill)
returns BSplineCurves from GeomFill;
Create( C1, C2 : BSplineCurve from Geom;
Type : FillingStyle from GeomFill)
returns BSplineCurves from GeomFill;
---Purpose: Constructs a framework for building a BSpline surface from either
-- - the four contiguous BSpline curves, C1, C2, C3 and C4, or
-- - the three contiguous BSpline curves, C1, C2 and C3, or
-- - the two contiguous BSpline curves, C1 and C2.
-- The type of filling style Type to be used is one of:
-- - GeomFill_Stretch - the style with the flattest patch
-- - GeomFill_Coons - a rounded style of patch with
-- less depth than that of Curved
-- - GeomFill_Curved - the style with the most rounded
-- patch.Constructs a framework for building a BSpline
-- surface common to the two BSpline curves, C1 and C2.
-- Exceptions
-- Standard_ConstructionError if the curves are not contiguous.
Init( me : in out;
C1, C2, C3, C4 : BSplineCurve from Geom;
Type : FillingStyle from GeomFill)
raises
ConstructionError from Standard
---Purpose: if the curves cannot be joined
is static;
Init( me : in out;
C1, C2, C3 : BSplineCurve from Geom;
Type : FillingStyle from GeomFill)
raises
ConstructionError from Standard
---Purpose: if the curves cannot be joined
is static;
Init( me : in out;
C1, C2 : BSplineCurve from Geom;
Type : FillingStyle from GeomFill)
is static;
---Purpose: Initializes or reinitializes this algorithm with two, three,
-- or four curves - C1, C2, C3, and C4 - and Type, one
-- of the following filling styles:
-- - GeomFill_Stretch - the style with the flattest patch
-- - GeomFill_Coons - a rounded style of patch with
-- less depth than that of Curved
-- - GeomFill_Curved - the style with the most rounded patch.
-- Exceptions
-- Standard_ConstructionError if the curves are not contiguous.
Surface(me) returns BSplineSurface from Geom
---Purpose: Returns the BSpline surface Surface resulting from
-- the computation performed by this algorithm.
---C++: return const&
---C++: inline
is static;
fields
mySurface : BSplineSurface from Geom;
end BSplineCurves;

View File

@@ -0,0 +1,596 @@
// File: GeomFill_BSplineCurves.cxx
// Created: Wed Oct 6 16:09:19 1993
// Author: Bruno DUMORTIER
// <dub@sdsun1>
#include <GeomFill_BSplineCurves.ixx>
#include <GeomFill_Filling.hxx>
#include <GeomFill_Stretch.hxx>
#include <GeomFill_Coons.hxx>
#include <GeomFill_Curved.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <TColStd_Array2OfReal.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColgp_Array2OfPnt.hxx>
#include <Standard_NotImplemented.hxx>
#include <BSplCLib.hxx>
#include <Precision.hxx>
//=======================================================================
//function : Arrange
//purpose : Internal Use Only
// This function is used to prepare the Filling: The Curves
// are arranged in this way:
//
// CC3
// ----->-----
// | |
// | |
// | |
// CC4 ^ ^ CC2
// | |
// | |
// ----->-----
// CC1 = C1
//=======================================================================
Standard_Boolean Arrange(const Handle(Geom_BSplineCurve)& C1,
const Handle(Geom_BSplineCurve)& C2,
const Handle(Geom_BSplineCurve)& C3,
const Handle(Geom_BSplineCurve)& C4,
Handle(Geom_BSplineCurve)& CC1,
Handle(Geom_BSplineCurve)& CC2,
Handle(Geom_BSplineCurve)& CC3,
Handle(Geom_BSplineCurve)& CC4,
const Standard_Real Tol )
{
Handle(Geom_BSplineCurve) GC[4];
Handle(Geom_BSplineCurve) Dummy;
GC[0] = Handle(Geom_BSplineCurve)::DownCast(C1->Copy());
GC[1] = Handle(Geom_BSplineCurve)::DownCast(C2->Copy());
GC[2] = Handle(Geom_BSplineCurve)::DownCast(C3->Copy());
GC[3] = Handle(Geom_BSplineCurve)::DownCast(C4->Copy());
Standard_Integer i,j;
Standard_Boolean Trouve;
for (i=1; i<=3; i++) {
Trouve = Standard_False;
for ( j=i; j<=3 && !Trouve; j++) {
if (GC[j]->StartPoint().Distance( GC[i-1]->EndPoint()) < Tol) {
Dummy = GC[i];
GC[i] = GC[j];
GC[j] = Dummy;
Trouve = Standard_True;
}
else if (GC[j]->EndPoint().Distance( GC[i-1]->EndPoint()) < Tol) {
GC[j] = Handle(Geom_BSplineCurve)::DownCast(GC[j]->Reversed());
Dummy = GC[i];
GC[i] = GC[j];
GC[j] = Dummy;
Trouve = Standard_True;
}
}
if (!Trouve) return Standard_False;
}
CC1 = GC[0];
CC2 = GC[1];
CC3 = Handle(Geom_BSplineCurve)::DownCast( GC[2]->Reversed());
CC4 = Handle(Geom_BSplineCurve)::DownCast( GC[3]->Reversed());
return Standard_True;
}
//=======================================================================
//function : SetSameDistribution
//purpose : Internal Use Only
//=======================================================================
Standard_Integer SetSameDistribution(Handle(Geom_BSplineCurve)& C1,
Handle(Geom_BSplineCurve)& C2 )
{
Standard_Integer nbp1 = C1->NbPoles();
Standard_Integer nbk1 = C1->NbKnots();
TColgp_Array1OfPnt P1(1,nbp1);
TColStd_Array1OfReal W1(1,nbp1);
W1.Init(1.);
TColStd_Array1OfReal K1(1,nbk1);
TColStd_Array1OfInteger M1(1,nbk1);
C1->Poles(P1);
if( C1->IsRational())
C1->Weights(W1);
C1->Knots(K1);
C1->Multiplicities(M1);
Standard_Integer nbp2 = C2->NbPoles();
Standard_Integer nbk2 = C2->NbKnots();
TColgp_Array1OfPnt P2(1,nbp2);
TColStd_Array1OfReal W2(1,nbp2);
W2.Init(1.);
TColStd_Array1OfReal K2(1,nbk2);
TColStd_Array1OfInteger M2(1,nbk2);
C2->Poles(P2);
if( C2->IsRational())
C2->Weights(W2);
C2->Knots(K2);
C2->Multiplicities(M2);
Standard_Real K11 = K1( 1 );
Standard_Real K12 = K1(nbk1);
Standard_Real K21 = K2( 1 );
Standard_Real K22 = K2(nbk2);
if ( (K12-K11) > (K22-K21)) {
BSplCLib::Reparametrize( K11, K12, K2);
C2->SetKnots(K2);
}
else if ( (K12-K11) < (K22-K21)) {
BSplCLib::Reparametrize( K21, K22, K1);
C1->SetKnots(K1);
}
else if(Abs(K12-K11) > Precision::PConfusion()) {
BSplCLib::Reparametrize( K11, K12, K2);
C2->SetKnots(K2);
}
Standard_Integer NP,NK;
if ( BSplCLib::PrepareInsertKnots(C1->Degree(),Standard_False,
K1,M1,K2,M2,NP,NK,Precision::PConfusion(),
Standard_False)) {
TColgp_Array1OfPnt NewP(1, NP);
TColStd_Array1OfReal NewW(1, NP);
TColStd_Array1OfReal NewK(1, NK);
TColStd_Array1OfInteger NewM(1, NK);
BSplCLib::InsertKnots(C1->Degree(),Standard_False,
P1,W1,K1,M1,K2,M2,
NewP,NewW,NewK,NewM,Precision::PConfusion(),
Standard_False);
if ( C1->IsRational()) {
C1 = new Geom_BSplineCurve(NewP,NewW,NewK,NewM,C1->Degree());
}
else {
C1 = new Geom_BSplineCurve(NewP,NewK,NewM,C1->Degree());
}
BSplCLib::InsertKnots(C2->Degree(),Standard_False,
P2,W2,K2,M2,K1,M1,
NewP,NewW,NewK,NewM,Precision::PConfusion(),
Standard_False);
if ( C2->IsRational()) {
C2 = new Geom_BSplineCurve(NewP,NewW,NewK,NewM,C2->Degree());
}
else {
C2 = new Geom_BSplineCurve(NewP,NewK,NewM,C2->Degree());
}
}
else {
Standard_ConstructionError::Raise(" ");
}
return C1->NbPoles();
}
//=======================================================================
//function : GeomFill_BSplineCurves
//purpose :
//=======================================================================
GeomFill_BSplineCurves::GeomFill_BSplineCurves()
{
}
//=======================================================================
//function : GeomFill_BSplineCurves
//purpose :
//=======================================================================
GeomFill_BSplineCurves::GeomFill_BSplineCurves
(const Handle(Geom_BSplineCurve)& C1,
const Handle(Geom_BSplineCurve)& C2,
const Handle(Geom_BSplineCurve)& C3,
const Handle(Geom_BSplineCurve)& C4,
const GeomFill_FillingStyle Type )
{
Init( C1, C2, C3, C4, Type);
}
//=======================================================================
//function : GeomFill_BSplineCurves
//purpose :
//=======================================================================
GeomFill_BSplineCurves::GeomFill_BSplineCurves
(const Handle(Geom_BSplineCurve)& C1,
const Handle(Geom_BSplineCurve)& C2,
const Handle(Geom_BSplineCurve)& C3,
const GeomFill_FillingStyle Type )
{
Init( C1, C2, C3, Type);
}
//=======================================================================
//function : GeomFill_BSplineCurves
//purpose :
//=======================================================================
GeomFill_BSplineCurves::GeomFill_BSplineCurves
(const Handle(Geom_BSplineCurve)& C1,
const Handle(Geom_BSplineCurve)& C2,
const GeomFill_FillingStyle Type )
{
Init( C1, C2, Type);
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_BSplineCurves::Init
(const Handle(Geom_BSplineCurve)& C1,
const Handle(Geom_BSplineCurve)& C2,
const Handle(Geom_BSplineCurve)& C3,
const Handle(Geom_BSplineCurve)& C4,
const GeomFill_FillingStyle Type )
{
// On ordonne les courbes
Handle(Geom_BSplineCurve) CC1, CC2, CC3, CC4;
Standard_Real Tol = Precision::Confusion();
#ifndef No_Exception
Standard_Boolean IsOK =
#endif
Arrange( C1, C2, C3, C4, CC1, CC2, CC3, CC4, Tol);
Standard_ConstructionError_Raise_if
(!IsOK, " GeomFill_BSplineCurves: Courbes non jointives");
// Mise en conformite des degres
Standard_Integer Deg1 = CC1->Degree();
Standard_Integer Deg2 = CC2->Degree();
Standard_Integer Deg3 = CC3->Degree();
Standard_Integer Deg4 = CC4->Degree();
Standard_Integer DegU = Max( Deg1, Deg3);
Standard_Integer DegV = Max( Deg2, Deg4);
if ( Deg1 < DegU) CC1->IncreaseDegree(DegU);
if ( Deg2 < DegV) CC2->IncreaseDegree(DegV);
if ( Deg3 < DegU) CC3->IncreaseDegree(DegU);
if ( Deg4 < DegV) CC4->IncreaseDegree(DegV);
// Mise en conformite des distributions de noeuds
Standard_Integer NbUPoles = SetSameDistribution(CC1,CC3);
Standard_Integer NbVPoles = SetSameDistribution(CC2,CC4);
if(Type == GeomFill_CoonsStyle) {
Standard_ConstructionError_Raise_if
(NbUPoles < 4 || NbVPoles < 4, " GeomFill_BSplineCurves: invalid filling style");
}
TColgp_Array1OfPnt P1(1,NbUPoles);
TColgp_Array1OfPnt P2(1,NbVPoles);
TColgp_Array1OfPnt P3(1,NbUPoles);
TColgp_Array1OfPnt P4(1,NbVPoles);
CC1->Poles(P1);
CC2->Poles(P2);
CC3->Poles(P3);
CC4->Poles(P4);
// Traitement des courbes rationelles
Standard_Boolean isRat = ( CC1->IsRational() || CC2->IsRational() ||
CC3->IsRational() || CC4->IsRational() );
TColStd_Array1OfReal W1(1,NbUPoles);
TColStd_Array1OfReal W3(1,NbUPoles);
TColStd_Array1OfReal W2(1,NbVPoles);
TColStd_Array1OfReal W4(1,NbVPoles);
W1.Init(1.);
W2.Init(1.);
W3.Init(1.);
W4.Init(1.);
if ( isRat) {
if (CC1->IsRational()) {
CC1->Weights(W1);
}
if (CC2->IsRational()) {
CC2->Weights(W2);
}
if (CC3->IsRational()) {
CC3->Weights(W3);
}
if (CC4->IsRational()) {
CC4->Weights(W4);
}
}
GeomFill_Filling Caro;
if (isRat) {
switch (Type)
{
case GeomFill_StretchStyle :
Caro = GeomFill_Stretch( P1, P2, P3, P4, W1, W2, W3, W4);
break;
case GeomFill_CoonsStyle :
Caro = GeomFill_Coons ( P1, P4, P3, P2, W1, W4, W3, W2);
break;
case GeomFill_CurvedStyle :
Caro = GeomFill_Curved ( P1, P2, P3, P4, W1, W2, W3, W4);
break;
}
}
else {
switch (Type)
{
case GeomFill_StretchStyle :
Caro = GeomFill_Stretch( P1, P2, P3, P4);
break;
case GeomFill_CoonsStyle :
Caro = GeomFill_Coons ( P1, P4, P3, P2);
break;
case GeomFill_CurvedStyle :
Caro = GeomFill_Curved ( P1, P2, P3, P4);
break;
}
}
NbUPoles = Caro.NbUPoles();
NbVPoles = Caro.NbVPoles();
TColgp_Array2OfPnt Poles(1,NbUPoles,1,NbVPoles);
// Creation de la surface
Standard_Integer NbUKnot = CC1->NbKnots();
TColStd_Array1OfReal UKnots(1,NbUKnot);
TColStd_Array1OfInteger UMults(1,NbUKnot);
CC1->Knots(UKnots);
CC1->Multiplicities(UMults);
Standard_Integer NbVKnot = CC2->NbKnots();
TColStd_Array1OfReal VKnots(1,NbVKnot);
TColStd_Array1OfInteger VMults(1,NbVKnot);
CC2->Knots(VKnots);
CC2->Multiplicities(VMults);
Caro.Poles(Poles);
if (Caro.isRational()) {
TColStd_Array2OfReal Weights(1,NbUPoles, 1,NbVPoles);
Caro.Weights(Weights);
mySurface = new Geom_BSplineSurface(Poles , Weights,
UKnots , VKnots,
UMults , VMults,
CC1->Degree(), CC2->Degree());
}
else {
mySurface = new Geom_BSplineSurface(Poles ,
UKnots , VKnots,
UMults , VMults,
CC1->Degree(), CC2->Degree());
}
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_BSplineCurves::Init
(const Handle(Geom_BSplineCurve)& C1,
const Handle(Geom_BSplineCurve)& C2,
const Handle(Geom_BSplineCurve)& C3,
const GeomFill_FillingStyle Type )
{
Handle(Geom_BSplineCurve) C4;
TColgp_Array1OfPnt Poles(1,2);
TColStd_Array1OfReal Knots(1,2);
TColStd_Array1OfInteger Mults(1,2);
Standard_Real Tol = Precision::Confusion();
Tol = Tol * Tol;
if(C1->StartPoint().SquareDistance(C2->StartPoint()) > Tol &&
C1->StartPoint().SquareDistance(C2->EndPoint()) > Tol )
Poles( 1) = C1->StartPoint();
else
Poles( 1) = C1->EndPoint();
if(C3->StartPoint().SquareDistance(C2->StartPoint()) > Tol &&
C3->StartPoint().SquareDistance(C2->EndPoint()) > Tol )
Poles( 2) = C3->StartPoint();
else
Poles( 2) = C3->EndPoint();
Knots( 1) = C2->Knot(C2->FirstUKnotIndex());
Knots( 2) = C2->Knot(C2->LastUKnotIndex());
Mults( 1) = Mults( 2) = 2;
C4 = new Geom_BSplineCurve( Poles, Knots, Mults, 1);
Init( C1, C2, C3, C4, Type);
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_BSplineCurves::Init
(const Handle(Geom_BSplineCurve)& C1,
const Handle(Geom_BSplineCurve)& C2,
const GeomFill_FillingStyle Type )
{
Handle(Geom_BSplineCurve)
CC1 = Handle(Geom_BSplineCurve)::DownCast(C1->Copy());
Handle(Geom_BSplineCurve)
CC2 = Handle(Geom_BSplineCurve)::DownCast(C2->Copy());
Standard_Integer Deg1 = CC1->Degree();
Standard_Integer Deg2 = CC2->Degree();
Standard_Boolean isRat = ( CC1->IsRational() || CC2->IsRational());
if ( Type != GeomFill_CurvedStyle) {
Standard_Integer DegU = Max( Deg1, Deg2);
if ( CC1->Degree() < DegU ) CC1->IncreaseDegree(DegU);
if ( CC2->Degree() < DegU ) CC2->IncreaseDegree(DegU);
// Mise en conformite des distributions de noeuds
Standard_Integer NbPoles = SetSameDistribution(CC1,CC2);
TColgp_Array2OfPnt Poles(1,NbPoles, 1,2);
TColgp_Array1OfPnt P1( 1, NbPoles);
TColgp_Array1OfPnt P2( 1, NbPoles);
CC1->Poles(P1);
CC2->Poles(P2);
Standard_Integer i;
for (i=1; i<=NbPoles; i++) {
Poles(i, 1) = P1(i);
Poles(i, 2) = P2(i);
}
Standard_Integer NbUKnots = CC1->NbKnots();
TColStd_Array1OfReal UKnots( 1, NbUKnots);
TColStd_Array1OfInteger UMults( 1, NbUKnots);
CC1->Knots(UKnots);
CC1->Multiplicities(UMults);
// Standard_Integer NbVKnots = 2;
TColStd_Array1OfReal VKnots( 1, 2);
TColStd_Array1OfInteger VMults( 1, 2);
VKnots( 1) = 0;
VKnots( 2) = 1;
VMults( 1) = 2;
VMults( 2) = 2;
// Traitement des courbes rationelles
if (isRat) {
TColStd_Array2OfReal Weights(1,NbPoles, 1,2);
TColStd_Array1OfReal W1(1,NbPoles);
TColStd_Array1OfReal W2(1,NbPoles);
W1.Init(1.);
W2.Init(1.);
if ( isRat) {
if (CC1->IsRational()) {
CC1->Weights(W1);
}
if (CC2->IsRational()) {
CC2->Weights(W2);
}
for (i=1; i<=NbPoles; i++) {
Weights(i, 1) = W1( i);
Weights(i, 2) = W2( i);
}
}
mySurface = new Geom_BSplineSurface(Poles , Weights,
UKnots , VKnots,
UMults , VMults,
CC1->Degree(), 1,
CC1->IsPeriodic(),
Standard_False);
}
else {
mySurface = new Geom_BSplineSurface(Poles ,
UKnots , VKnots,
UMults , VMults,
CC1->Degree(), 1);
}
}
else {
Standard_Real Eps = Precision::Confusion();
Standard_Boolean IsOK = Standard_False;
if ( CC1->StartPoint().IsEqual(CC2->StartPoint(),Eps)) {
IsOK = Standard_True;
}
else if ( CC1->StartPoint().IsEqual(CC2->EndPoint(),Eps)) {
CC2->Reverse();
IsOK = Standard_True;
}
else if ( CC1->EndPoint().IsEqual(CC2->StartPoint(),Eps)) {
C1->Reverse();
IsOK = Standard_True;
}
else if ( CC1->EndPoint().IsEqual(CC2->EndPoint(),Eps)) {
CC1->Reverse();
CC2->Reverse();
IsOK = Standard_True;
}
Standard_ConstructionError_Raise_if
(!IsOK, " GeomFill_BSplineCurves: Courbes non jointives");
Standard_Integer NbUPoles = CC1->NbPoles();
Standard_Integer NbVPoles = CC2->NbPoles();
TColgp_Array1OfPnt P1(1,NbUPoles);
TColgp_Array1OfPnt P2(1,NbVPoles);
CC1->Poles(P1);
CC2->Poles(P2);
Standard_Integer NbUKnots = CC1->NbKnots();
Standard_Integer NbVKnots = CC2->NbKnots();
TColStd_Array1OfReal UKnots(1,NbUKnots);
TColStd_Array1OfReal VKnots(1,NbVKnots);
TColStd_Array1OfInteger UMults(1,NbUKnots);
TColStd_Array1OfInteger VMults(1,NbVKnots);
CC1->Knots(UKnots);
CC1->Multiplicities(UMults);
CC2->Knots(VKnots);
CC2->Multiplicities(VMults);
TColStd_Array1OfReal W1(1,NbUPoles);
TColStd_Array1OfReal W2(1,NbVPoles);
W1.Init(1.);
W2.Init(1.);
GeomFill_Filling Caro;
if ( isRat) {
if (CC1->IsRational()) {
CC1->Weights(W1);
}
if (CC2->IsRational()) {
CC2->Weights(W2);
}
Caro = GeomFill_Curved( P1, P2, W1, W2);
}
else {
Caro = GeomFill_Curved( P1, P2);
}
NbUPoles = Caro.NbUPoles();
NbVPoles = Caro.NbVPoles();
TColgp_Array2OfPnt Poles(1,NbUPoles,1,NbVPoles);
Caro.Poles(Poles);
if (Caro.isRational()) {
TColStd_Array2OfReal Weights(1,NbUPoles, 1,NbVPoles);
Caro.Weights(Weights);
mySurface = new Geom_BSplineSurface(Poles , Weights,
UKnots , VKnots,
UMults , VMults,
Deg1 , Deg2,
Standard_False, Standard_False);
}
else {
mySurface = new Geom_BSplineSurface(Poles ,
UKnots , VKnots,
UMults , VMults,
Deg1 , Deg2,
Standard_False, Standard_False);
}
}
}

View File

@@ -0,0 +1,16 @@
// File: GeomFill_BSplineCurves.lxx
// Created: Wed Oct 6 16:10:28 1993
// Author: Bruno DUMORTIER
// <dub@sdsun1>
//=======================================================================
//function : Surface
//purpose :
//=======================================================================
inline const Handle(Geom_BSplineSurface)& GeomFill_BSplineCurves::Surface()
const
{
return mySurface;
}

View File

@@ -0,0 +1,94 @@
-- File: GeomFill_BezierCurves.cdl
-- Created: Wed Oct 6 10:30:09 1993
-- Author: Bruno DUMORTIER
-- <dub@sdsun1>
---Copyright: Matra Datavision 1993
class BezierCurves from GeomFill
---Purpose: This class provides an algorithm for constructing a Bezier surface filled from
-- contiguous Bezier curves which form its boundaries.
-- The algorithm accepts two, three or four Bezier curves
-- as the boundaries of the target surface.
-- A range of filling styles - more or less rounded, more or less flat - is available.
-- A BezierCurves object provides a framework for:
-- - defining the boundaries, and the filling style of the surface
-- - implementing the construction algorithm
-- - consulting the result.
-- Warning
-- Some problems may show up with rational curves.
uses
BezierCurve from Geom,
BezierSurface from Geom,
FillingStyle from GeomFill
raises
ConstructionError from Standard
is
Create;
--- Purpose: Constructs an empty framework for building a Bezier
-- surface from contiguous Bezier curves.
-- You use the Init function to define the boundaries of the surface.
Create( C1, C2, C3, C4 : BezierCurve from Geom;
Type : FillingStyle from GeomFill)
returns BezierCurves from GeomFill;
---Purpose: Constructs a framework for building a Bezier surface
-- from the four contiguous Bezier curves, C1, C2, C3 and C4
-- Raises Standard_ConstructionError if the curves are not contiguous.
Create( C1, C2, C3 : BezierCurve from Geom;
Type : FillingStyle from GeomFill)
returns BezierCurves from GeomFill;
---Purpose: Constructs a framework for building a Bezier surface
-- from the three contiguous Bezier curves, C1, C2 and C3
-- Raises Standard_ConstructionError if the curves are not contiguous.
Create( C1, C2 : BezierCurve from Geom;
Type : FillingStyle from GeomFill)
returns BezierCurves from GeomFill;
---Purpose: Constructs a framework for building a Bezier surface
-- from the two contiguous Bezier curves, C1 and C2
-- Raises Standard_ConstructionError if the curves are not contiguous.
Init( me : in out;
C1, C2, C3, C4 : BezierCurve from Geom;
Type : FillingStyle from GeomFill)
raises
ConstructionError from Standard
---Purpose: if the curves cannot be joined
is static;
Init( me : in out;
C1, C2, C3 : BezierCurve from Geom;
Type : FillingStyle from GeomFill)
raises
ConstructionError from Standard
---Purpose: if the curves cannot be joined
is static;
Init( me : in out;
C1, C2 : BezierCurve from Geom;
Type : FillingStyle from GeomFill)
is static;
---Purpose: Initializes or reinitializes this algorithm with two, three,
-- or four curves - C1, C2, C3, and C4 - and Type, one
-- of the following filling styles:
-- - GeomFill_Stretch - the style with the flattest patch
-- - GeomFill_Coons - a rounded style of patch with
-- less depth than that of Curved
-- - GeomFill_Curved - the style with the most rounded patch.
-- Exceptions
-- Standard_ConstructionError if the curves are not contiguous.
Surface(me) returns BezierSurface from Geom
---Purpose: Returns the Bezier surface resulting from the
-- computation performed by this algorithm.
---C++: return const&
---C++: inline
is static;
fields
mySurface : BezierSurface from Geom;
end BezierCurves;

View File

@@ -0,0 +1,472 @@
// File: GeomFill_BezierCurves.cxx
// Created: Wed Oct 6 11:03:48 1993
// Author: Bruno DUMORTIER
// <dub@sdsun1>
#include <GeomFill_BezierCurves.ixx>
#include <GeomFill_Filling.hxx>
#include <GeomFill_Stretch.hxx>
#include <GeomFill_Coons.hxx>
#include <GeomFill_Curved.hxx>
#include <Precision.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_BezierSurface.hxx>
#include <Standard_ConstructionError.hxx>
#include <Standard_NotImplemented.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColgp_Array2OfPnt.hxx>
#include <TColStd_Array2OfReal.hxx>
#include <TColStd_Array1OfReal.hxx>
//=======================================================================
//function : SetSameWeights
//purpose : Internal Use Only
// This function uses the following property of Rational
// BezierCurves
// if Wi = Weight(i); Pi = Pole(i); n = NbPoles
// with any a,b,c != 0,
// i n-i
// The transformation : Wi = a * b * c doesn't modify
// the geometry of the curve.
// Only the length of the derivatives are changed.
//=======================================================================
void SetSameWeights(TColStd_Array1OfReal& W1,
TColStd_Array1OfReal& W2,
TColStd_Array1OfReal& W3,
TColStd_Array1OfReal& W4 )
{
Standard_Real Eps = Precision::Confusion();
Standard_Integer NU = W1.Length();
Standard_Integer NV = W2.Length();
Standard_Real A = ( W1( 1) * W2( 1)) / ( W1( NU) * W2( NV));
Standard_Real B = ( W3( 1) * W4( 1)) / ( W3( NU) * W4( NV));
Standard_Integer i;
Standard_Real Alfa = W1( NU) / W2( 1);
for ( i=1; i<=NV; i++) {
W2(i) *= Alfa;
}
Standard_Real Beta = W2( NV) / W3( NU);
for ( i=1; i<=NU; i++) {
W3(i) *= Beta;
}
Standard_Real Gamma = W3( 1) / W4( NV);
for ( i=1; i<=NV; i++) {
W4(i) *= Gamma;
}
if ( Abs(A-B) > Eps) {
Standard_Real w = Pow( W1(1)/W4(1), 1./(Standard_Real)(NV-1));
Standard_Real x = w;
for ( i=NV-1; i>=1; i--) {
W4(i) *= x;
x *= w;
}
}
}
//=======================================================================
//function : Arrange
//purpose : Internal Use Only
// This function is used to prepare the Filling: The Curves
// are arranged in this way:
//
// CC3
// ----->-----
// | |
// | |
// | |
// CC4 ^ ^ CC2
// | |
// | |
// ----->-----
// CC1 = C1
//=======================================================================
Standard_Boolean Arrange(const Handle(Geom_BezierCurve)& C1,
const Handle(Geom_BezierCurve)& C2,
const Handle(Geom_BezierCurve)& C3,
const Handle(Geom_BezierCurve)& C4,
Handle(Geom_BezierCurve)& CC1,
Handle(Geom_BezierCurve)& CC2,
Handle(Geom_BezierCurve)& CC3,
Handle(Geom_BezierCurve)& CC4,
const Standard_Real Tol )
{
Handle(Geom_BezierCurve) GC[4];
Handle(Geom_BezierCurve) Dummy;
GC[0] = Handle(Geom_BezierCurve)::DownCast(C1->Copy());
GC[1] = Handle(Geom_BezierCurve)::DownCast(C2->Copy());
GC[2] = Handle(Geom_BezierCurve)::DownCast(C3->Copy());
GC[3] = Handle(Geom_BezierCurve)::DownCast(C4->Copy());
Standard_Integer i,j;
Standard_Boolean Trouve;
for (i=1; i<=3; i++) {
Trouve = Standard_False;
for ( j=i; j<=3 && !Trouve; j++) {
if (GC[j]->StartPoint().Distance( GC[i-1]->EndPoint()) < Tol) {
Dummy = GC[i];
GC[i] = GC[j];
GC[j] = Dummy;
Trouve = Standard_True;
}
else if (GC[j]->EndPoint().Distance( GC[i-1]->EndPoint()) < Tol) {
GC[j] = Handle(Geom_BezierCurve)::DownCast(GC[j]->Reversed());
Dummy = GC[i];
GC[i] = GC[j];
GC[j] = Dummy;
Trouve = Standard_True;
}
}
if (!Trouve) return Standard_False;
}
CC1 = GC[0];
CC2 = GC[1];
CC3 = Handle(Geom_BezierCurve)::DownCast( GC[2]->Reversed());
CC4 = Handle(Geom_BezierCurve)::DownCast( GC[3]->Reversed());
return Standard_True;
}
//=======================================================================
//function : GeomFill_BezierCurves
//purpose :
//=======================================================================
GeomFill_BezierCurves::GeomFill_BezierCurves()
{
}
//=======================================================================
//function : GeomFill_BezierCurves
//purpose :
//=======================================================================
GeomFill_BezierCurves::GeomFill_BezierCurves(const Handle(Geom_BezierCurve)& C1,
const Handle(Geom_BezierCurve)& C2,
const Handle(Geom_BezierCurve)& C3,
const Handle(Geom_BezierCurve)& C4,
const GeomFill_FillingStyle Type )
{
Init( C1, C2, C3, C4, Type);
}
//=======================================================================
//function : GeomFill_BezierCurves
//purpose :
//=======================================================================
GeomFill_BezierCurves::GeomFill_BezierCurves(const Handle(Geom_BezierCurve)& C1,
const Handle(Geom_BezierCurve)& C2,
const Handle(Geom_BezierCurve)& C3,
const GeomFill_FillingStyle Type )
{
Init( C1, C2, C3, Type);
}
//=======================================================================
//function : GeomFill_BezierCurves
//purpose :
//=======================================================================
GeomFill_BezierCurves::GeomFill_BezierCurves(const Handle(Geom_BezierCurve)& C1,
const Handle(Geom_BezierCurve)& C2,
const GeomFill_FillingStyle Type )
{
Init( C1, C2, Type);
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_BezierCurves::Init(const Handle(Geom_BezierCurve)& C1,
const Handle(Geom_BezierCurve)& C2,
const Handle(Geom_BezierCurve)& C3,
const Handle(Geom_BezierCurve)& C4,
const GeomFill_FillingStyle Type )
{
// On ordonne les courbes
Handle(Geom_BezierCurve) CC1, CC2, CC3, CC4;
Standard_Real Tol = Precision::Confusion();
#ifndef No_Exception
Standard_Boolean IsOK =
#endif
Arrange( C1, C2, C3, C4, CC1, CC2, CC3, CC4, Tol);
Standard_ConstructionError_Raise_if
(!IsOK, " GeomFill_BezierCurves: Courbes non jointives");
// Mise en conformite des degres
Standard_Integer DegU = Max( CC1->Degree(), CC3->Degree());
Standard_Integer DegV = Max( CC2->Degree(), CC4->Degree());
if (Type == GeomFill_CoonsStyle) {
DegU = Max( DegU, 3);
DegV = Max( DegV, 3);
}
if ( CC1->Degree() < DegU ) CC1->Increase(DegU);
if ( CC2->Degree() < DegV ) CC2->Increase(DegV);
if ( CC3->Degree() < DegU ) CC3->Increase(DegU);
if ( CC4->Degree() < DegV ) CC4->Increase(DegV);
TColgp_Array1OfPnt P1(1,DegU+1);
TColgp_Array1OfPnt P3(1,DegU+1);
TColgp_Array1OfPnt P2(1,DegV+1);
TColgp_Array1OfPnt P4(1,DegV+1);
CC1->Poles(P1);
CC2->Poles(P2);
CC3->Poles(P3);
CC4->Poles(P4);
// Traitement des courbes rationelles
Standard_Boolean isRat = ( CC1->IsRational() || CC2->IsRational() ||
CC3->IsRational() || CC4->IsRational() );
TColStd_Array1OfReal W1(1,DegU+1);
TColStd_Array1OfReal W3(1,DegU+1);
TColStd_Array1OfReal W2(1,DegV+1);
TColStd_Array1OfReal W4(1,DegV+1);
W1.Init(1.);
W2.Init(1.);
W3.Init(1.);
W4.Init(1.);
if ( isRat) {
if (CC1->IsRational()) {
CC1->Weights(W1);
}
if (CC2->IsRational()) {
CC2->Weights(W2);
}
if (CC3->IsRational()) {
CC3->Weights(W3);
}
if (CC4->IsRational()) {
CC4->Weights(W4);
}
}
GeomFill_Filling Caro;
if (isRat) {
// Mise en conformite des poids aux coins.
SetSameWeights( W1, W2, W3, W4);
switch (Type)
{
case GeomFill_StretchStyle :
Caro = GeomFill_Stretch( P1, P2, P3, P4, W1, W2, W3, W4);
break;
case GeomFill_CoonsStyle :
Caro = GeomFill_Coons ( P1, P4, P3, P2, W1, W4, W3, W2);
break;
case GeomFill_CurvedStyle :
Caro = GeomFill_Curved ( P1, P2, P3, P4, W1, W2, W3, W4);
break;
}
}
else {
switch (Type)
{
case GeomFill_StretchStyle :
Caro = GeomFill_Stretch( P1, P2, P3, P4);
break;
case GeomFill_CoonsStyle :
Caro = GeomFill_Coons ( P1, P4, P3, P2);
break;
case GeomFill_CurvedStyle :
Caro = GeomFill_Curved ( P1, P2, P3, P4);
break;
}
}
Standard_Integer NbUPoles = Caro.NbUPoles();
Standard_Integer NbVPoles = Caro.NbVPoles();
TColgp_Array2OfPnt Poles(1,NbUPoles,1,NbVPoles);
Caro.Poles(Poles);
if (Caro.isRational()) {
TColStd_Array2OfReal Weights(1,NbUPoles, 1,NbVPoles);
Caro.Weights(Weights);
mySurface = new Geom_BezierSurface(Poles,Weights);
}
else {
mySurface = new Geom_BezierSurface(Poles);
}
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_BezierCurves::Init(const Handle(Geom_BezierCurve)& C1,
const Handle(Geom_BezierCurve)& C2,
const Handle(Geom_BezierCurve)& C3,
const GeomFill_FillingStyle Type )
{
Handle(Geom_BezierCurve) C4;
TColgp_Array1OfPnt Poles(1,2);
Standard_Real Tol = Precision::Confusion();
Tol = Tol * Tol;
if(C1->StartPoint().SquareDistance(C2->StartPoint()) > Tol &&
C1->StartPoint().SquareDistance(C2->EndPoint()) > Tol )
Poles( 1) = C1->StartPoint();
else
Poles( 1) = C1->EndPoint();
if(C3->StartPoint().SquareDistance(C2->StartPoint()) > Tol &&
C3->StartPoint().SquareDistance(C2->EndPoint()) > Tol )
Poles( 2) = C3->StartPoint();
else
Poles( 2) = C3->EndPoint();
// Poles(1) = C1->StartPoint();
// Poles(2) = C1->StartPoint();
C4 = new Geom_BezierCurve(Poles);
Init( C1, C2, C3, C4, Type);
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_BezierCurves::Init(const Handle(Geom_BezierCurve)& C1,
const Handle(Geom_BezierCurve)& C2,
const GeomFill_FillingStyle Type )
{
Handle(Geom_BezierCurve)
CC1 = Handle(Geom_BezierCurve)::DownCast(C1->Copy());
Handle(Geom_BezierCurve)
CC2 = Handle(Geom_BezierCurve)::DownCast(C2->Copy());
Standard_Integer Deg1 = CC1->Degree();
Standard_Integer Deg2 = CC2->Degree();
Standard_Boolean isRat = ( CC1->IsRational() || CC2->IsRational());
if ( Type != GeomFill_CurvedStyle) {
Standard_Integer DegU = Max( Deg1, Deg2);
if ( CC1->Degree() < DegU ) CC1->Increase(DegU);
if ( CC2->Degree() < DegU ) CC2->Increase(DegU);
TColgp_Array2OfPnt Poles( 1, DegU+1, 1, 2);
TColgp_Array1OfPnt P1(1,DegU+1);
TColgp_Array1OfPnt P2(1,DegU+1);
CC1->Poles(P1);
CC2->Poles(P2);
Standard_Integer i;
for (i=1; i<=DegU+1; i++) {
Poles(i, 1) = P1(i);
Poles(i, 2) = P2(i);
}
if (isRat) {
TColStd_Array1OfReal W1(1,DegU+1);
TColStd_Array1OfReal W2(1,DegU+1);
W1.Init(1.);
W2.Init(1.);
if (CC1->IsRational()) {
CC1->Weights(W1);
}
if (CC2->IsRational()) {
CC2->Weights(W2);
}
TColStd_Array2OfReal Weights(1,DegU+1, 1,2);
for ( i=1; i<=DegU+1; i++) {
Weights(i, 1) = W1(i);
Weights(i, 2) = W2(i);
}
mySurface = new Geom_BezierSurface(Poles,Weights);
}
else {
mySurface = new Geom_BezierSurface(Poles);
}
}
else {
TColgp_Array1OfPnt P1(1,Deg1+1);
TColgp_Array1OfPnt P2(1,Deg2+1);
Standard_Real Eps = Precision::Confusion();
Standard_Boolean IsOK = Standard_False;
if ( CC1->StartPoint().IsEqual(CC2->StartPoint(),Eps)) {
IsOK = Standard_True;
}
else if ( CC1->StartPoint().IsEqual(CC2->EndPoint(),Eps)) {
CC2->Reverse();
IsOK = Standard_True;
}
else if ( CC1->EndPoint().IsEqual(CC2->StartPoint(),Eps)) {
C1->Reverse();
IsOK = Standard_True;
}
else if ( CC1->EndPoint().IsEqual(CC2->EndPoint(),Eps)) {
CC1->Reverse();
CC2->Reverse();
IsOK = Standard_True;
}
Standard_ConstructionError_Raise_if
(!IsOK, " GeomFill_BezierCurves: Courbes non jointives");
CC1->Poles(P1);
CC2->Poles(P2);
TColStd_Array1OfReal W1(1,Deg1+1);
TColStd_Array1OfReal W2(1,Deg2+1);
W1.Init(1.);
W2.Init(1.);
GeomFill_Filling Caro;
if ( isRat) {
if (CC1->IsRational()) {
CC1->Weights(W1);
}
if (CC2->IsRational()) {
CC2->Weights(W2);
}
Caro = GeomFill_Curved( P1, P2, W1, W2);
}
else {
Caro = GeomFill_Curved( P1, P2);
}
Standard_Integer NbUPoles = Caro.NbUPoles();
Standard_Integer NbVPoles = Caro.NbVPoles();
TColgp_Array2OfPnt Poles(1,NbUPoles,1,NbVPoles);
Caro.Poles(Poles);
if (Caro.isRational()) {
TColStd_Array2OfReal Weights(1,NbUPoles, 1,NbVPoles);
Caro.Weights(Weights);
mySurface = new Geom_BezierSurface(Poles,Weights);
}
else {
mySurface = new Geom_BezierSurface(Poles);
}
}
}

View File

@@ -0,0 +1,22 @@
// File: GeomFill_BezierCurves.lxx
// Created: Wed Oct 6 15:57:04 1993
// Author: Bruno DUMORTIER
// <dub@sdsun1>
//=======================================================================
//function : Surface
//purpose :
//=======================================================================
inline const Handle(Geom_BezierSurface)& GeomFill_BezierCurves::Surface()
const
{
return mySurface;
}

View File

@@ -0,0 +1,105 @@
-- File: GeomFill_BoundWithSurf.cdl
-- Created: Tue Oct 17 15:02:27 1995
-- Author: Laurent BOURESCHE
-- <lbo@phylox>
---Copyright: Matra Datavision 1995
class BoundWithSurf from GeomFill inherits Boundary from GeomFill
---Purpose: Defines a 3d curve as a boundary for a
-- GeomFill_ConstrainedFilling algorithm.
-- This curve is attached to an existing surface.
-- Defines a constrained boundary for filling
-- the computations are done with a CurveOnSurf and a
-- normals field defined by the normalized normal to
-- the surface along the PCurve.
uses
Pnt from gp,
Vec from gp,
Function from Law,
CurveOnSurface from Adaptor3d
is
Create(CurveOnSurf : CurveOnSurface from Adaptor3d;
Tol3d : Real from Standard;
Tolang : Real from Standard)
returns mutable BoundWithSurf from GeomFill;
---Purpose:
-- Constructs a boundary object defined by the 3d curve CurveOnSurf.
-- The surface to be filled along this boundary will be in the
-- tolerance range defined by Tol3d.
-- What's more, at each point of CurveOnSurf, the angle
-- between the normal to the surface to be filled along this
-- boundary, and the normal to the surface on which
-- CurveOnSurf lies, must not be greater than TolAng.
-- This object is to be used as a boundary for a
-- GeomFill_ConstrainedFilling framework.
-- Warning
-- CurveOnSurf is an adapted curve, that is, an object
-- which is an interface between:
-- - the services provided by a curve lying on a surface from the package Geom
-- - and those required of the curve by the computation algorithm which uses it.
-- The adapted curve is created in the following way:
-- Handle(Geom_Surface) mySurface = ... ;
-- Handle(Geom2d_Curve) myParamCurve = ... ;
-- // where myParamCurve is a 2D curve in the parametric space of the surface mySurface
-- Handle(GeomAdaptor_HSurface)
-- Surface = new
-- GeomAdaptor_HSurface(mySurface);
-- Handle(Geom2dAdaptor_HCurve)
-- ParamCurve = new
-- Geom2dAdaptor_HCurve(myParamCurve);
-- CurveOnSurf = Adaptor3d_CurveOnSurface(ParamCurve,Surface);
-- The boundary is then constructed with the CurveOnSurf object:
-- Standard_Real Tol = ... ;
-- Standard_Real TolAng = ... ;
-- myBoundary = GeomFill_BoundWithSurf (
-- CurveOnSurf, Tol, TolAng );
Value(me;
U : Real from Standard)
returns Pnt from gp;
D1(me;
U : Real from Standard;
P : out Pnt from gp;
V : out Vec from gp) ;
HasNormals(me)
returns Boolean from Standard
is redefined;
Norm(me;
U : Real from Standard)
returns Vec from gp
is redefined;
D1Norm(me;
U : Real from Standard;
N : out Vec from gp;
DN : out Vec from gp)
is redefined;
Reparametrize(me : mutable;
First, Last : Real from Standard;
HasDF, HasDL : Boolean from Standard;
DF, DL : Real from Standard;
Rev : Boolean from Standard);
Bounds(me; First, Last : out Real from Standard);
IsDegenerated(me) returns Boolean from Standard;
fields
myConS : CurveOnSurface from Adaptor3d;
myPar : Function from Law;
end BoundWithSurf;

View File

@@ -0,0 +1,195 @@
// File: GeomFill_BoundWithSurf.cxx
// Created: Thu Oct 19 14:52:52 1995
// Author: Laurent BOURESCHE
// <lbo@phylox>
#include <GeomFill_BoundWithSurf.ixx>
#include <Law.hxx>
#include <Law_BSpFunc.hxx>
#include <Adaptor3d_HSurface.hxx>
#include <Adaptor2d_HCurve2d.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec2d.hxx>
//=======================================================================
//function : GeomFill_BoundWithSurf
//purpose :
//=======================================================================
GeomFill_BoundWithSurf::GeomFill_BoundWithSurf
(const Adaptor3d_CurveOnSurface& CurveOnSurf,
const Standard_Real Tol3d,
const Standard_Real Tolang) :
GeomFill_Boundary(Tol3d,Tolang), myConS(CurveOnSurf)
{
}
//=======================================================================
//function : Value
//purpose :
//=======================================================================
gp_Pnt GeomFill_BoundWithSurf::Value(const Standard_Real U) const
{
Standard_Real x = U;
if(!myPar.IsNull()) x = myPar->Value(U);
return myConS.Value(x);
}
//=======================================================================
//function : D1
//purpose :
//=======================================================================
void GeomFill_BoundWithSurf::D1(const Standard_Real U,
gp_Pnt& P,
gp_Vec& V) const
{
Standard_Real x = U, dx = 1.;
if(!myPar.IsNull()) myPar->D1(U,x,dx);
myConS.D1(x, P, V);
V.Multiply(dx);
}
//=======================================================================
//function : HasNormals
//purpose :
//=======================================================================
Standard_Boolean GeomFill_BoundWithSurf::HasNormals() const
{
return Standard_True;
}
//=======================================================================
//function : Norm
//purpose :
//=======================================================================
gp_Vec GeomFill_BoundWithSurf::Norm(const Standard_Real U) const
{
// voir s il ne faudrait pas utiliser LProp ou autre.
if (!HasNormals())
Standard_Failure::Raise("BoundWithSurf Norm : pas de contrainte");
// Handle(Adaptor3d_HSurface)& S = myConS.GetSurface();
// Handle(Adaptor2d_HCurve2d)& C2d = myConS.GetCurve();
Standard_Real x,y;
Standard_Real w = U;
if(!myPar.IsNull()) w = myPar->Value(U);
myConS.GetCurve()->Value(w).Coord(x,y);
gp_Pnt P;
gp_Vec Su, Sv;
myConS.GetSurface()->D1(x,y,P,Su,Sv);
Su.Cross(Sv);
Su.Normalize();
return Su;
}
//=======================================================================
//function : D1Norm
//purpose :
//=======================================================================
void GeomFill_BoundWithSurf::D1Norm(const Standard_Real U,
gp_Vec& N,
gp_Vec& DN) const
{
if (!HasNormals())
Standard_Failure::Raise("BoundWithSurf Norm : pas de contrainte");
// Handle(Adaptor3d_HSurface)& S = myConS.GetSurface();
// Handle(Adaptor2d_HCurve2d)& C2d = myConS.GetCurve();
gp_Pnt2d P2d;
gp_Vec2d V2d;
Standard_Real x,y,dx,dy;
Standard_Real w = U, dw = 1.;
if(!myPar.IsNull()) myPar->D1(U,w,dw);
myConS.GetCurve()->D1(w,P2d,V2d);
P2d.Coord(x,y);
V2d.Multiply(dw);
V2d.Coord(dx,dy);
gp_Pnt P;
gp_Vec Su, Sv, Suu, Suv, Svv;
myConS.GetSurface()->D2(x,y,P,Su,Sv, Suu, Svv, Suv);
N = Su.Crossed(Sv);
N.Normalize();
Standard_Real nsuu = N.Dot(Suu), nsuv = N.Dot(Suv), nsvv = N.Dot(Svv);
Standard_Real susu = Su.Dot(Su), susv = Su.Dot(Sv), svsv = Sv.Dot(Sv);
Standard_Real deno = (susu*svsv) - (susv*susv);
if(Abs(deno < 1.e-16)){
// on embraye sur un calcul approche, c est mieux que rien!?!
gp_Vec temp = Norm(U + 1.e-12);
DN = N.Multiplied(-1.);
DN.Add(temp);
DN.Multiply(1.e-12);
}
else{
Standard_Real a = (-nsuu*svsv + nsuv*susv)/deno;
Standard_Real b = ( nsuu*susv - nsuv*susu)/deno;
Standard_Real c = (-nsuv*svsv + nsvv*susv)/deno;
Standard_Real d = ( nsuv*susv - nsvv*susu)/deno;
gp_Vec temp1 = Su.Multiplied(a);
gp_Vec temp2 = Sv.Multiplied(b);
temp1.Add(temp2);
temp2 = Su.Multiplied(c);
gp_Vec temp3 = Sv.Multiplied(d);
temp2.Add(temp3);
temp1.Multiply(dx);
temp2.Multiply(dy);
DN = temp1.Added(temp2);
}
}
//=======================================================================
//function : Reparametrize
//purpose :
//=======================================================================
void GeomFill_BoundWithSurf::Reparametrize(const Standard_Real First,
const Standard_Real Last,
const Standard_Boolean HasDF,
const Standard_Boolean HasDL,
const Standard_Real DF,
const Standard_Real DL,
const Standard_Boolean Rev)
{
Handle(Law_BSpline) curve = Law::Reparametrize(myConS,
First,Last,
HasDF,HasDL,DF,DL,
Rev,30);
myPar = new Law_BSpFunc();
(*((Handle_Law_BSpFunc*) &myPar))->SetCurve(curve);
}
//=======================================================================
//function : Bounds
//purpose :
//=======================================================================
void GeomFill_BoundWithSurf::Bounds(Standard_Real& First,
Standard_Real& Last) const
{
if(!myPar.IsNull()) myPar->Bounds(First,Last);
else{
First = myConS.FirstParameter();
Last = myConS.LastParameter();
}
}
//=======================================================================
//function : IsDegenerated
//purpose :
//=======================================================================
Standard_Boolean GeomFill_BoundWithSurf::IsDegenerated() const
{
return Standard_False;
}

View File

@@ -0,0 +1,87 @@
-- File: GeomFill_Boundary.cdl
-- Created: Tue Oct 17 14:45:36 1995
-- Author: Laurent BOURESCHE
-- <lbo@phylox>
---Copyright: Matra Datavision 1995
deferred class Boundary from GeomFill inherits TShared from MMgt
---Purpose: Root class to define a boundary which will form part of a
-- contour around a gap requiring filling.
-- The GeomFill package provides two classes to define constrained boundaries:
-- - GeomFill_SimpleBound to define an unattached boundary
-- - GeomFill_BoundWithSurf to define a boundary attached to a surface.
-- These objects are used to define the boundaries for a
-- GeomFill_ConstrainedFilling framework.
uses
Pnt from gp,
Vec from gp
is
Initialize(Tol3d : Real from Standard;
Tolang : Real from Standard);
Value(me;
U : Real from Standard)
returns Pnt from gp
is deferred;
D1(me;
U : Real from Standard;
P : out Pnt from gp;
V : out Vec from gp)
is deferred;
HasNormals(me)
returns Boolean from Standard
is virtual;
-- the methods giving informations about normals are implemented
-- with a raise.
-- use a call to HasNormals before calling Norm or D1Norm.
Norm(me;
U : Real from Standard)
returns Vec from gp
is virtual;
D1Norm(me;
U : Real from Standard;
N : out Vec from gp;
DN : out Vec from gp)
is virtual;
Reparametrize(me : mutable;
First, Last : Real from Standard;
HasDF, HasDL : Boolean from Standard;
DF, DL : Real from Standard;
Rev : Boolean from Standard)
is deferred;
Points(me; PFirst, PLast : out Pnt from gp);
Bounds(me; First, Last : out Real from Standard)
is deferred;
IsDegenerated(me)
returns Boolean from Standard
is deferred;
Tol3d(me) returns Real from Standard;
Tol3d(me : mutable;
Tol : Real from Standard);
Tolang(me) returns Real from Standard;
Tolang(me : mutable;
Tol : Real from Standard);
fields
myT3d : Real from Standard;
myTang : Real from Standard;
end Boundary;

View File

@@ -0,0 +1,113 @@
// File: GeomFill_Boundary.cxx
// Created: Fri Nov 3 15:13:27 1995
// Author: Laurent BOURESCHE
// <lbo@phylox>
#include <GeomFill_Boundary.ixx>
//=======================================================================
//function : GeomFill_Boundary
//purpose :
//=======================================================================
GeomFill_Boundary::GeomFill_Boundary(const Standard_Real Tol3d,
const Standard_Real Tolang):
myT3d(Tol3d), myTang(Tolang)
{
}
//=======================================================================
//function : HasNormals
//purpose :
//=======================================================================
Standard_Boolean GeomFill_Boundary::HasNormals() const
{
return Standard_False;
}
//=======================================================================
//function : Norm
//purpose :
//=======================================================================
gp_Vec GeomFill_Boundary::Norm(const Standard_Real ) const
{
Standard_Failure::Raise("GeomFill_Boundary::Norm : Undefined normals");
return gp_Vec();
}
//=======================================================================
//function : D1Norm
//purpose :
//=======================================================================
void GeomFill_Boundary::D1Norm(const Standard_Real , gp_Vec& , gp_Vec& ) const
{
Standard_Failure::Raise("GeomFill_Boundary::Norm : Undefined normals");
}
//=======================================================================
//function : Points
//purpose :
//=======================================================================
void GeomFill_Boundary::Points(gp_Pnt& PFirst, gp_Pnt& PLast) const
{
Standard_Real f,l;
Bounds(f,l);
PFirst = Value(f);
PLast = Value(l);
}
//=======================================================================
//function : Tol3d
//purpose :
//=======================================================================
Standard_Real GeomFill_Boundary::Tol3d() const
{
return myT3d;
}
//=======================================================================
//function : Tol3d
//purpose :
//=======================================================================
void GeomFill_Boundary::Tol3d(const Standard_Real Tol)
{
myT3d = Tol;
}
//=======================================================================
//function : Tolang
//purpose :
//=======================================================================
Standard_Real GeomFill_Boundary::Tolang() const
{
return myTang;
}
//=======================================================================
//function : Tolang
//purpose :
//=======================================================================
void GeomFill_Boundary::Tolang(const Standard_Real Tol)
{
myTang = Tol;
}

View File

@@ -0,0 +1,229 @@
-- File: GeomFill_CircularBlendFunc.cdl
-- Created: Fri Jul 11 13:33:09 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
private class CircularBlendFunc from GeomFill
inherits SweepFunction from Approx
---Purpose: Circular Blend Function to approximate by
-- SweepApproximation from Approx
uses
HCurve from Adaptor3d,
BSplineCurve from Geom,
ParameterisationType from Convert,
Array1OfPnt from TColgp,
Array1OfVec from TColgp,
Array1OfPnt2d from TColgp,
Array1OfVec2d from TColgp,
Array1OfReal from TColStd,
Array1OfInteger from TColStd,
Shape from GeomAbs,
Pnt from gp
raises OutOfRange from Standard
is
Create( Path : HCurve from Adaptor3d;
Curve1 : HCurve from Adaptor3d;
Curve2 : HCurve from Adaptor3d;
Radius : Real from Standard;
Polynomial : Boolean = Standard_False)
---Purpose: Create a Blend with a constant radius with 2
-- guide-line. <FShape> sets the type of fillet
-- surface. The -- default value is Convert_TgtThetaOver2 (classical --
-- nurbs -- representation of circles).
-- ChFi3d_QuasiAngular -- corresponds to a nurbs
-- representation of circles -- which
-- parameterisation matches the circle one. --
-- ChFi3d_Polynomial corresponds to a polynomial --
-- representation of circles.
returns CircularBlendFunc from GeomFill;
-- --
-- To compute Sections and derivatives Sections
--
--
D0(me : mutable;
Param: Real;
First, Last : Real;
Poles : out Array1OfPnt from TColgp;
Poles2d : out Array1OfPnt2d from TColgp;
Weigths : out Array1OfReal from TColStd)
---Purpose: compute the section for v = param
returns Boolean is redefined;
D1(me : mutable;
Param: Real;
First, Last : Real;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
Poles2d : out Array1OfPnt2d from TColgp;
DPoles2d : out Array1OfVec2d from TColgp;
Weigths : out Array1OfReal from TColStd;
DWeigths : out Array1OfReal from TColStd)
---Purpose: compute the first derivative in v direction of the
-- section for v = param
returns Boolean
is redefined;
D2(me : mutable;
Param: Real;
First, Last : Real;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
D2Poles : out Array1OfVec from TColgp;
Poles2d : out Array1OfPnt2d from TColgp;
DPoles2d : out Array1OfVec2d from TColgp;
D2Poles2d : out Array1OfVec2d from TColgp;
Weigths : out Array1OfReal from TColStd;
DWeigths : out Array1OfReal from TColStd;
D2Weigths : out Array1OfReal from TColStd)
---Purpose: compute the second derivative in v direction of the
-- section for v = param
returns Boolean
is redefined;
--
-- General Information On The Function
--
Nb2dCurves(me)
---Purpose: get the number of 2d curves to approximate.
returns Integer is redefined;
SectionShape(me; NbPoles : out Integer from Standard;
NbKnots : out Integer from Standard;
Degree : out Integer from Standard)
---Purpose: get the format of an section
is redefined;
Knots(me; TKnots: out Array1OfReal from TColStd)
---Purpose: get the Knots of the section
is redefined;
Mults(me; TMults: out Array1OfInteger from TColStd)
---Purpose: get the Multplicities of the section
is redefined;
IsRational(me)
---Purpose: Returns if the section is rationnal or not
returns Boolean is redefined;
--
-- Mangement of continuity
--
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>. May be one if Continuity(me) >= <S>
returns Integer is redefined;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is redefined;
SetInterval(me: mutable; First, Last: Real from Standard)
---Purpose: Sets the bounds of the parametric interval on
-- the fonction
-- This determines the derivatives in these values if the
-- function is not Cn.
is redefined;
--
-- To help computation of Tolerance
--
-- Evaluation of error, in 2d space, or on rational function, is
-- dificult. The folowing methodes can help
--
--
GetTolerance(me;
BoundTol, SurfTol, AngleTol : Real;
Tol3d : out Array1OfReal)
---Purpose: Returns the tolerance to reach in approximation
-- to respecte
-- BoundTol error at the Boundary
-- AngleTol tangent error at the Boundary (in radian)
-- SurfTol error inside the surface.
is redefined;
SetTolerance(me : mutable; Tol3d, Tol2d : Real)
---Purpose: Is usfull, if (me) have to be run numerical
-- algorithme to perform D0, D1 or D2
is redefined;
BarycentreOfSurf(me)
---Purpose: Get the barycentre of Surface. An very poor
-- estimation is sufficent. This information is usefull
-- to perform well conditionned rational approximation.
-- Warning: Used only if <me> IsRational
returns Pnt from gp
is redefined;
MaximalSection(me) returns Real
---Purpose: Returns the length of the maximum section. This
-- information is usefull to perform well conditionned rational
-- approximation.
-- Warning: Used only if <me> IsRational
is redefined;
GetMinimalWeight(me; Weigths : out Array1OfReal from TColStd)
---Purpose: Compute the minimal value of weight for each poles
-- of all sections. This information is usefull to
-- perform well conditionned rational approximation.
-- Warning: Used only if <me> IsRational
is redefined;
-- Private methods
Discret(me:mutable)
is private;
fields
myBary : Pnt from gp;
myRadius : Real;
myMinW : Real;
maxang : Real;
minang : Real;
distmin : Real;
myPath : HCurve from Adaptor3d;
myCurve1 : HCurve from Adaptor3d;
myCurve2 : HCurve from Adaptor3d;
myTPath : HCurve from Adaptor3d;
myTCurve1 : HCurve from Adaptor3d;
myTCurve2 : HCurve from Adaptor3d;
myDegree : Integer;
myNbKnots : Integer;
myNbPoles : Integer;
myTConv : ParameterisationType from Convert;
myreverse : Boolean;
end CircularBlendFunc;

View File

@@ -0,0 +1,622 @@
// File: GeomFill_CircularBlendFunc.cxx
// Created: Fri Jul 11 15:54:00 1997
// Author: Philippe MANGIN
// <pmn@sgi29>
#include <GeomFill_CircularBlendFunc.ixx>
#include <GeomFill.hxx>
#include <GCPnts_QuasiUniformDeflection.hxx>
#include <Precision.hxx>
#include <Adaptor3d_HCurve.hxx>
#include <TColStd_SequenceOfReal.hxx>
#include <TColStd_Array1OfReal.hxx>
#if DRAW
#include <GeomAdaptor_HCurve.hxx>
#include <Geom_BSplineCurve.hxx>
#include <DrawTrSurf.hxx>
static Standard_Integer NbSections = 0;
#endif
GeomAbs_Shape GeomFillNextShape(const GeomAbs_Shape S)
{
switch (S) {
case GeomAbs_C0 :
return GeomAbs_C1;
case GeomAbs_C1 :
return GeomAbs_C2;
case GeomAbs_C2 :
return GeomAbs_C3;
case GeomAbs_C3 :
return GeomAbs_CN;
default :
return GeomAbs_CN;
}
}
void GeomFillFusInt(const TColStd_Array1OfReal& I1,
const TColStd_Array1OfReal& I2,
TColStd_SequenceOfReal& Seq)
{
Standard_Integer ind1=1, ind2=1;
Standard_Real Epspar = Precision::PConfusion()*0.99;
// en suposant que le positionement fonctionne a PConfusion()/2
Standard_Real v1, v2;
// Initialisations : les IND1 et IND2 pointent sur le 1er element
// de chacune des 2 tables a traiter.
//--- On remplit TABSOR en parcourant TABLE1 et TABLE2 simultanement ---
//------------------ en eliminant les occurrences multiples ------------
while ((ind1<=I1.Upper()) && (ind2<=I2.Upper())) {
v1 = I1(ind1);
v2 = I2(ind2);
if (Abs(v1-v2)<= Epspar) {
// Ici les elements de I1 et I2 conviennent .
Seq.Append((v1+v2)/2);
ind1++;
ind2++;
}
else if (v1 < v2) {
// Ici l' element de I1 convient.
Seq.Append(v1);
ind1++;
}
else {
// Ici l' element de TABLE2 convient.
Seq.Append(v2);
ind2++;
}
}
if (ind1>I1.Upper()) {
//----- Ici I1 est epuise, on complete avec la fin de TABLE2 -------
for (; ind2<=I2.Upper(); ind2++) {
Seq.Append(I2(ind2));
}
}
if (ind2>I2.Upper()) {
//----- Ici I2 est epuise, on complete avec la fin de I1 -------
for (; ind1<=I1.Upper(); ind1++) {
Seq.Append(I1(ind1));
}
}
}
GeomFill_CircularBlendFunc::
GeomFill_CircularBlendFunc(const Handle(Adaptor3d_HCurve)& Path,
const Handle(Adaptor3d_HCurve)& Curve1,
const Handle(Adaptor3d_HCurve)& Curve2,
const Standard_Real Radius,
const Standard_Boolean Polynomial)
: maxang(RealFirst()),
minang(RealLast()),
distmin(RealLast())
{
// Recopie des arguments
myPath = myTPath = Path;
myCurve1 = myTCurve1 = Curve1;
myCurve2 = myTCurve2 = Curve2;
myRadius = Radius;
// Estimations numeriques
Discret();
// Type de convertion ?
if (Polynomial) myTConv=Convert_Polynomial;
else if(maxang > 0.65*PI)
myTConv=Convert_QuasiAngular; //car c'est Continue
else myTConv = Convert_TgtThetaOver2;
//car c'est le plus performant
// On en deduit la structure
GeomFill::GetShape(maxang,
myNbPoles, myNbKnots,
myDegree, myTConv);
}
void GeomFill_CircularBlendFunc::Discret()
{
Standard_Real TFirst = myPath->FirstParameter();
Standard_Real TLast = myPath->LastParameter(), T;
Standard_Integer ii;
Standard_Real L1, L2, L;
Handle(Adaptor3d_HCurve) C;
gp_Pnt P1, P2, P3, Center;
gp_Vec DCenter;
P1 = myCurve1->Value(TFirst);
P2 = myCurve1->Value((TFirst+TLast)/2.);
P3 = myCurve1->Value(TLast);
L1 = P1.Distance(P2) + P2.Distance(P3);
P1 = myCurve2->Value(TFirst);
P2 = myCurve2->Value((TFirst+TLast)/2.);
P3 = myCurve2->Value(TLast);
L2 = P1.Distance(P2) + P2.Distance(P3);
if (L1>L2) {
L = L1;
C = myCurve1;
}
else {
L = L2;
C = myCurve2;
}
Standard_Real Fleche = 1.e-2 * L;
Standard_Real Angle, Cosa, Percent;
GCPnts_QuasiUniformDeflection Samp;
Samp.Initialize(C->GetCurve(), Fleche);
myBary.SetCoord(0.,0.,0.);
gp_Vec ns1, ns2;
if (Samp.IsDone()) {
Percent = ((Standard_Real)1)/(2*Samp.NbPoints());
// char name[100];
for (ii=1; ii<=Samp.NbPoints(); ii++) {
T = Samp.Parameter(ii);
myCurve1->D0(T, P1);
myCurve2->D0(T, P2);
/*
sprintf(name,"PNT_%d",NbSections++);
DrawTrSurf::Set(name, P1);
sprintf(name,"PNT_%d",NbSections++);
DrawTrSurf::Set(name, P2);*/
myPath->D0(T, Center);
ns1.SetXYZ( Center.XYZ() - P1.XYZ());
ns2.SetXYZ( Center.XYZ() - P2.XYZ());
ns1.Normalize();
ns2.Normalize();
Cosa = ns1.Dot(ns2);
if(Cosa > 1.) {Cosa = 1.;}
Angle = Abs(ACos(Cosa));
if (Angle>maxang) maxang = Angle;
if (Angle<minang) minang = Angle;
distmin = Min( distmin, P1.Distance(P2));
myBary.ChangeCoord() += (P1.XYZ()+P2.XYZ());
}
}
else {
Standard_Real Delta = (TLast-TFirst)/20;
Percent = ((Standard_Real)1)/42;
for (ii=0, T=TFirst; ii<=20; ii++, T+=Delta) {
myCurve1->D0(T, P1);
myCurve2->D0(T, P2);
myPath->D0(T, Center);
ns1.SetXYZ( Center.XYZ() - P1.XYZ());
ns2.SetXYZ( Center.XYZ() - P2.XYZ());
ns1.Normalize();
ns2.Normalize();
Cosa = ns1.Dot(ns2);
if(Cosa > 1.) Cosa = 1.;
Angle = Abs(ACos(Cosa));
if (Angle>maxang) maxang = Angle;
if (Angle<minang) minang = Angle;
distmin = Min( distmin, P1.Distance(P2));
myBary.ChangeCoord() += (P1.XYZ()+P2.XYZ());
}
}
myBary.ChangeCoord() *= Percent;
// Faut il inverser la trajectoire ?
T = (TFirst + TLast)/2;
myCurve1->D0(T, P1);
myCurve2->D0(T, P2);
myPath->D1(T, Center, DCenter);
ns1.SetXYZ( Center.XYZ() - P1.XYZ());
ns2.SetXYZ( Center.XYZ() - P2.XYZ());
myreverse = (DCenter.Dot(ns1.Crossed(ns2)) < 0);
}
Standard_Boolean GeomFill_CircularBlendFunc::D0(const Standard_Real Param,
const Standard_Real,
const Standard_Real,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfPnt2d&,
TColStd_Array1OfReal& Weigths)
{
gp_Pnt P1, P2, Center;
gp_Vec ns1, ns2, nplan;
gp_XYZ temp;
// Positionnement
myTPath->D0(Param, Center);
myTCurve1->D0(Param, P1);
myTCurve2->D0(Param, P2);
ns1.SetXYZ( Center.XYZ() - P1.XYZ());
ns2.SetXYZ( Center.XYZ() - P2.XYZ());
if (!ns1.IsParallel(ns2,1.e-9)) nplan = ns1.Crossed(ns2);
else {
myTPath->D1(Param, Center, nplan);
if (myreverse) nplan.Reverse();
}
// Normalisation
ns1.Normalize();
ns2.Normalize();
nplan.Normalize();
temp.SetLinearForm(myRadius, ns1.XYZ(),
myRadius, ns2.XYZ(),
1, P1.XYZ(),
P2.XYZ());
Center.ChangeCoord() = 0.5*temp;
// Section
GeomFill::GetCircle(myTConv,
ns1, ns2, nplan,
P1, P2,
myRadius, Center,
Poles, Weigths);
#if DRAW
// Handle(Geom_BSplineCurve) BS =
// new Geom_BSplineCurve(Poles,Weights,Knots,Mults,Degree);
// sprintf(name,"SECT_%d",NbSections++);
// DrawTrSurf::Set(name,BS);
#endif
return Standard_True;
}
Standard_Boolean GeomFill_CircularBlendFunc::D1(const Standard_Real Param,
// const Standard_Real First,
const Standard_Real ,
// const Standard_Real Last,
const Standard_Real ,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfVec& DPoles,
// TColgp_Array1OfPnt2d& Poles2d,
TColgp_Array1OfPnt2d& ,
// TColgp_Array1OfVec2d& DPoles2d,
TColgp_Array1OfVec2d& ,
TColStd_Array1OfReal& Weigths,
TColStd_Array1OfReal& DWeigths)
{
gp_Pnt P1, P2, Center;
Standard_Real invnorm1, invnorm2, invnormp;
// gp_Vec DCenter, D2Center, nplan, dnplan, DP1, DP2;
gp_Vec DCenter, nplan, dnplan, DP1, DP2;
// gp_Vec ns1, ns2, Dns1, Dns2, vtmp;
gp_Vec ns1, ns2, Dns1, Dns2;
gp_XYZ temp;
// Positionemment
myTPath ->D1(Param, Center, DCenter);
myTCurve1->D1(Param, P1, DP1);
myTCurve2->D1(Param, P2, DP2);
ns1.SetXYZ( Center.XYZ() - P1.XYZ());
ns2.SetXYZ( Center.XYZ() - P2.XYZ());
Dns1 = DCenter - DP1;
Dns2 = DCenter - DP2;
if (!ns1.IsParallel(ns2,1.e-9)) {
nplan = ns1.Crossed(ns2);
dnplan = Dns1.Crossed(ns2).Added( ns1.Crossed(Dns2));
}
else {
myTPath->D2(Param, Center, nplan, dnplan);
if (myreverse) {
nplan.Reverse();
dnplan.Reverse();
}
}
// Normalisation
invnorm1 = ((Standard_Real) 1) / ns1.Magnitude();
invnorm2 = ((Standard_Real) 1) / ns2.Magnitude();
ns1 *= invnorm1;
Dns1.SetLinearForm( -Dns1.Dot(ns1), ns1, Dns1);
Dns1 *= invnorm1;
ns2 *= invnorm2;
Dns2.SetLinearForm(-Dns2.Dot(ns2), ns2, Dns2);
Dns2 *= invnorm2;
temp.SetLinearForm(myRadius, ns1.XYZ(),
myRadius, ns2.XYZ(),
1, P1.XYZ(), P2.XYZ());
Center.ChangeCoord() = 0.5*temp;
DCenter.SetLinearForm(myRadius, Dns1,
myRadius, Dns2,
1, DP1, DP2);
DCenter *= 0.5;
invnormp = ((Standard_Real)1) / nplan.Magnitude();
nplan *= invnormp;
dnplan.SetLinearForm(-dnplan.Dot(nplan), nplan, dnplan);
dnplan *= invnormp;
GeomFill::GetCircle(myTConv,
ns1, ns2,
Dns1, Dns2,
nplan, dnplan,
P1, P2,
DP1, DP2,
myRadius, 0,
Center, DCenter,
Poles, DPoles,
Weigths, DWeigths);
return Standard_True;
}
Standard_Boolean GeomFill_CircularBlendFunc::D2(const Standard_Real Param,
// const Standard_Real First,
const Standard_Real ,
// const Standard_Real Last,
const Standard_Real ,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfVec& DPoles,
TColgp_Array1OfVec& D2Poles,
// TColgp_Array1OfPnt2d& Poles2d,
TColgp_Array1OfPnt2d& ,
// TColgp_Array1OfVec2d& DPoles2d,
TColgp_Array1OfVec2d& ,
// TColgp_Array1OfVec2d& D2Poles2d,
TColgp_Array1OfVec2d& ,
TColStd_Array1OfReal& Weigths,
TColStd_Array1OfReal& DWeigths,
TColStd_Array1OfReal& D2Weigths)
{
gp_Pnt P1, P2, Center;
Standard_Real invnorm1, invnorm2, invnormp, sc;
gp_Vec DCenter, D2Center, DP1, DP2, D2P1, D2P2;
gp_Vec nplan, dnplan, d2nplan;
gp_Vec ns1, ns2, Dns1, Dns2, D2ns1, D2ns2;
gp_XYZ temp;
// Positionement
myTPath ->D2(Param, Center, DCenter, D2Center);
myTCurve1->D2(Param, P1, DP1, D2P1);
myTCurve2->D2(Param, P2, DP2, D2P2);
ns1.SetXYZ( Center.XYZ() - P1.XYZ());
Dns1 = DCenter - DP1;
D2ns1 = D2Center - D2P1;
ns2.SetXYZ( Center.XYZ() - P2.XYZ());
Dns2 = DCenter - DP2;
D2ns2 = D2Center - D2P2;
if (!ns1.IsParallel(ns2,1.e-9)) {
nplan = ns1.Crossed(ns2);
dnplan = Dns1.Crossed(ns2).Added( ns1.Crossed(Dns2));
d2nplan.SetLinearForm(1, D2ns1.Crossed(ns2),
2, Dns1.Crossed(Dns2),
ns1.Crossed(D2ns2));
}
else {
myTPath->D3(Param, Center, nplan, dnplan, d2nplan);
if (myreverse) {
nplan.Reverse();
dnplan.Reverse();
d2nplan.Reverse();
}
}
// Normalisation
invnorm1 = ((Standard_Real) 1) / ns1.Magnitude();
invnorm2 = ((Standard_Real) 1) / ns2.Magnitude();
ns1 *= invnorm1;
sc = Dns1.Dot(ns1);
D2ns1.SetLinearForm( 3*sc*sc*invnorm1 - D2ns1.Dot(ns1)
- invnorm1*Dns1.SquareMagnitude(), ns1,
-2*sc*invnorm1 , Dns1,
D2ns1);
Dns1.SetLinearForm( -Dns1.Dot(ns1), ns1, Dns1);
D2ns1 *= invnorm1;
Dns1 *= invnorm1;
ns2 *= invnorm2;
sc = Dns2.Dot(ns2);
D2ns2.SetLinearForm( 3*sc*sc*invnorm2 - D2ns2.Dot(ns2)
- invnorm2*Dns2.SquareMagnitude(), ns2,
-2*sc*invnorm2 , Dns2,
D2ns2);
Dns2.SetLinearForm(-sc, ns2, Dns2);
D2ns2 *= invnorm2;
Dns2 *= invnorm2;
temp.SetLinearForm(myRadius, ns1.XYZ(),
myRadius, ns2.XYZ(),
1, P1.XYZ(), P2.XYZ());
Center.ChangeCoord() = 0.5*temp;
DCenter.SetLinearForm(myRadius, Dns1,
myRadius, Dns2,
1, DP1, DP2);
DCenter *= 0.5;
D2Center.SetLinearForm(myRadius, D2ns1,
myRadius, D2ns2,
1, D2P1, D2P2);
D2Center *= 0.5;
invnormp = ((Standard_Real)1) / nplan.Magnitude();
nplan *= invnormp;
sc = dnplan.Dot(nplan);
d2nplan.SetLinearForm( 3*sc*sc*invnormp - d2nplan.Dot(nplan)
- invnormp*dnplan.SquareMagnitude(), nplan,
-2*sc*invnormp , dnplan,
d2nplan);
dnplan.SetLinearForm(-sc, nplan, dnplan);
dnplan *= invnormp;
d2nplan *= invnormp;
GeomFill::GetCircle(myTConv,
ns1, ns2,
Dns1, Dns2,
D2ns1, D2ns2,
nplan, dnplan, d2nplan,
P1, P2,
DP1, DP2,
D2P1, D2P2,
myRadius, 0, 0,
Center, DCenter, D2Center,
Poles, DPoles, D2Poles,
Weigths, DWeigths, D2Weigths);
return Standard_True;
}
Standard_Integer GeomFill_CircularBlendFunc::Nb2dCurves() const
{
return 0;
}
void GeomFill_CircularBlendFunc::SectionShape(Standard_Integer& NbPoles,
Standard_Integer& NbKnots,
Standard_Integer& Degree) const
{
NbPoles = myNbPoles;
NbKnots = myNbKnots;
Degree = myDegree;
}
void GeomFill_CircularBlendFunc::Knots(TColStd_Array1OfReal& TKnots) const
{
GeomFill::Knots(myTConv, TKnots);
}
void GeomFill_CircularBlendFunc::Mults(TColStd_Array1OfInteger& TMults) const
{
GeomFill::Mults(myTConv, TMults);
}
Standard_Boolean GeomFill_CircularBlendFunc::IsRational() const
{
return (myTConv != Convert_Polynomial);
}
Standard_Integer GeomFill_CircularBlendFunc::
NbIntervals(const GeomAbs_Shape S) const
{
Standard_Integer NbI_Center, NbI_Cb1, NbI_Cb2, ii;
NbI_Center = myPath->NbIntervals(GeomFillNextShape(S));
NbI_Cb1 = myCurve1->NbIntervals(S);
NbI_Cb2 = myCurve2->NbIntervals(S);
TColStd_Array1OfReal ICenter(1, NbI_Center+1);
TColStd_Array1OfReal ICb1(1, NbI_Cb1+1);
TColStd_Array1OfReal ICb2(1, NbI_Cb2+1);
TColStd_SequenceOfReal Inter;
myPath->Intervals(ICenter, GeomFillNextShape(S));
myCurve1->Intervals(ICb1, S);
myCurve2->Intervals(ICb2, S);
/* cout << "Intervals : " << S << endl;
cout << "-- Center-> " << endl;
for (ii=1; ii<=ICenter.Length(); ii++) cout << " , "<< ICenter(ii);
cout << endl; cout << endl;
cout << "-- Cb1-> " << endl;
for (ii=1; ii<=ICb1.Length(); ii++) cout << " , "<< ICb1(ii);
cout << endl; cout << endl;
cout << "-- Cb2-> " << endl;
for (ii=1; ii<=ICb2.Length(); ii++) cout << " , "<< ICb1(ii);
cout << endl; cout << endl;*/
GeomFillFusInt(ICb1, ICb2, Inter);
TColStd_Array1OfReal ICbs (1, Inter.Length());
for (ii=1; ii<=ICbs.Length(); ii++) ICbs(ii) = Inter(ii);
Inter.Clear();
GeomFillFusInt(ICenter, ICbs, Inter);
return Inter.Length()-1;
}
void GeomFill_CircularBlendFunc::
Intervals(TColStd_Array1OfReal& T, const GeomAbs_Shape S) const
{
Standard_Integer NbI_Center, NbI_Cb1, NbI_Cb2, ii;
NbI_Center = myPath->NbIntervals(GeomFillNextShape(S));
NbI_Cb1 = myCurve1->NbIntervals(S);
NbI_Cb2 = myCurve2->NbIntervals(S);
TColStd_Array1OfReal ICenter(1, NbI_Center+1);
TColStd_Array1OfReal ICb1(1, NbI_Cb1+1);
TColStd_Array1OfReal ICb2(1, NbI_Cb2+1);
TColStd_SequenceOfReal Inter;
myPath->Intervals(ICenter, GeomFillNextShape(S));
myCurve1->Intervals(ICb1, S);
myCurve2->Intervals(ICb2, S);
GeomFillFusInt(ICb1, ICb2, Inter);
TColStd_Array1OfReal ICbs (1, Inter.Length());
for (ii=1; ii<=ICbs.Length(); ii++) ICbs(ii) = Inter(ii);
Inter.Clear();
GeomFillFusInt(ICenter, ICbs, Inter);
// Recopie du resultat
for (ii=1; ii<=Inter.Length(); ii++) T(ii) = Inter(ii);
}
void GeomFill_CircularBlendFunc::SetInterval(const Standard_Real First,
const Standard_Real Last)
{
Standard_Real Eps = Precision::PConfusion();
myTPath = myPath->Trim(First, Last, Eps);
myTCurve1 = myCurve1->Trim(First, Last, Eps);
myTCurve2 = myCurve2->Trim(First, Last, Eps);
}
void GeomFill_CircularBlendFunc::GetTolerance(const Standard_Real BoundTol,
const Standard_Real SurfTol,
const Standard_Real AngleTol,
TColStd_Array1OfReal& Tol3d) const
{
Standard_Integer low = Tol3d.Lower() , up=Tol3d.Upper();
Standard_Real Tol;
Tol= GeomFill::GetTolerance(myTConv, minang,
myRadius, AngleTol, SurfTol);
Tol3d.Init(SurfTol);
Tol3d(low+1) = Tol3d(up-1) = Min(Tol, SurfTol);
Tol3d(low) = Tol3d(up) = Min(Tol, BoundTol);
}
void GeomFill_CircularBlendFunc::SetTolerance(const Standard_Real,
const Standard_Real)
{
// y rien a faire !
}
gp_Pnt GeomFill_CircularBlendFunc::BarycentreOfSurf() const
{
return myBary;
}
Standard_Real GeomFill_CircularBlendFunc::MaximalSection() const
{
return maxang*myRadius;
}
void GeomFill_CircularBlendFunc::
GetMinimalWeight(TColStd_Array1OfReal& Weigths) const
{
GeomFill::GetMinimalWeights(myTConv, minang, maxang, Weigths);
}

View File

@@ -0,0 +1,122 @@
-- File: GeomFill_ConstantBiNormal.cdl
-- Created: Tue Dec 9 18:33:12 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
class ConstantBiNormal from GeomFill
inherits TrihedronLaw from GeomFill
---Purpose: Defined an Trihedron Law where the BiNormal, is fixed
uses
HCurve from Adaptor3d,
Shape from GeomAbs,
Array1OfReal from TColStd,
Vec from gp,
Dir from gp,
Frenet from GeomFill
raises
OutOfRange, ConstructionError
is
Create(BiNormal : Dir from gp)
returns ConstantBiNormal from GeomFill;
Copy(me)
returns TrihedronLaw from GeomFill
is redefined;
SetCurve(me : mutable; C : HCurve from Adaptor3d)
is redefined;
--
--
--========== To compute Location and derivatives Location
--
D0(me : mutable;
Param: Real;
Tangent : out Vec from gp;
Normal : out Vec from gp;
BiNormal : out Vec from gp)
---Purpose: Computes Triedrhon on curve at parameter <Param>
returns Boolean is redefined;
D1(me : mutable;
Param: Real;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp)
---Purpose: Computes Triedrhon and derivative Trihedron on curve
-- at parameter <Param>
-- Warning : It used only for C1 or C2 aproximation
returns Boolean
is redefined;
D2(me : mutable;
Param: Real;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
D2Tangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
D2Normal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp;
D2BiNormal : out Vec from gp)
---Purpose: compute Trihedron on curve
-- first and seconde derivatives.
-- Warning : It used only for C2 aproximation
returns Boolean
is redefined;
--
-- =================== Management of continuity ===================
--
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>.
-- May be one if Continuity(me) >= <S>
returns Integer is redefined;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is redefined;
-- =================== To help computation of Tolerance ===============
GetAverageLaw(me : mutable;
ATangent : out Vec from gp;
ANormal : out Vec from gp;
ABiNormal : out Vec from gp)
---Purpose: Gets average value of Tangent(t) and Normal(t) it is usfull to
-- make fast approximation of rational surfaces.
is redefined;
-- =================== To help Particular case ===============
IsConstant(me)
---Purpose: Says if the law is Constant.
returns Boolean
is redefined;
IsOnlyBy3dCurve(me)
---Purpose: Return True.
returns Boolean
is redefined;
fields
BN : Vec from gp;
frenet : Frenet from GeomFill;
end ConstantBiNormal;

View File

@@ -0,0 +1,246 @@
// File: GeomFill_ConstantNormal.cxx
// Created: Tue Mar 3 09:32:04 1998
// Author: Roman BORISOV
// <rbv@ecolox.nnov.matra-dtv.fr>
#include <GeomFill_ConstantBiNormal.ixx>
#include <gp_Ax1.hxx>
#include <gp_Lin.hxx>
#include <Precision.hxx>
//=======================================================================
//function : FDeriv
//purpose : computes (F/|F|)'
//=======================================================================
static gp_Vec FDeriv(const gp_Vec& F, const gp_Vec& DF)
{
Standard_Real Norma = F.Magnitude();
gp_Vec Result = (DF - F*(F*DF)/(Norma*Norma))/Norma;
return Result;
}
//=======================================================================
//function : DDeriv
//purpose : computes (F/|F|)''
//=======================================================================
static gp_Vec DDeriv(const gp_Vec& F, const gp_Vec& DF, const gp_Vec& D2F)
{
Standard_Real Norma = F.Magnitude();
gp_Vec Result = (D2F - 2*DF*(F*DF)/(Norma*Norma))/Norma -
F*((DF.SquareMagnitude() + F*D2F
- 3*(F*DF)*(F*DF)/(Norma*Norma))/(Norma*Norma*Norma));
return Result;
}
GeomFill_ConstantBiNormal::GeomFill_ConstantBiNormal(const gp_Dir& BiNormal) : BN(BiNormal)
{
frenet = new GeomFill_Frenet();
}
Handle(GeomFill_TrihedronLaw) GeomFill_ConstantBiNormal::Copy() const
{
Handle(GeomFill_TrihedronLaw) copy = new GeomFill_ConstantBiNormal(gp_Dir(BN));
if (!myCurve.IsNull()) copy->SetCurve(myCurve);
return copy;
}
void GeomFill_ConstantBiNormal::SetCurve(const Handle(Adaptor3d_HCurve)& C)
{
GeomFill_TrihedronLaw::SetCurve(C);
if (! C.IsNull()) {
frenet->SetCurve(C);
}
}
Standard_Boolean GeomFill_ConstantBiNormal::D0(const Standard_Real Param,gp_Vec& Tangent,gp_Vec& Normal,gp_Vec& BiNormal)
{
// if BN^T != 0 then N = (BN^T).Normalized ; T = N^BN
// else T = (N^BN).Normalized ; N = BN^T
frenet->D0(Param, Tangent, Normal, BiNormal);
BiNormal = BN;
if(BiNormal.Crossed(Tangent).Magnitude() > Precision::Confusion()) {
Normal = BiNormal.Crossed(Tangent).Normalized();
Tangent = Normal.Crossed(BiNormal);
}
else {
Tangent = Normal.Crossed(BiNormal).Normalized();
Normal = BiNormal.Crossed(Tangent);
}
/*for Test
gp_Vec DTangent, D2Tangent, DNormal, D2Normal, DBiNormal, D2BiNormal;
D2(Param, Tangent, DTangent, D2Tangent,
Normal, DNormal, D2Normal, BiNormal, DBiNormal, D2BiNormal);
*/
return Standard_True;
}
Standard_Boolean GeomFill_ConstantBiNormal::D1(const Standard_Real Param,gp_Vec& Tangent,gp_Vec& DTangent,gp_Vec& Normal,gp_Vec& DNormal,gp_Vec& BiNormal,gp_Vec& DBiNormal)
{
gp_Vec F, DF;
frenet->D1(Param, Tangent, DTangent, Normal, DNormal, BiNormal, DBiNormal);
BiNormal = BN;
DBiNormal = gp_Vec(0, 0, 0);
if(BiNormal.Crossed(Tangent).Magnitude() > Precision::Confusion()) {
F = BiNormal.Crossed(Tangent);
DF = BiNormal.Crossed(DTangent);
Normal = F.Normalized();
DNormal = FDeriv(F, DF);
Tangent = Normal.Crossed(BiNormal);
DTangent = DNormal.Crossed(BiNormal);
}
else {
F = Normal.Crossed(BiNormal);
DF = DNormal.Crossed(BiNormal);
Tangent = F.Normalized();
DTangent = FDeriv(F, DF);
Normal = BiNormal.Crossed(Tangent);
DNormal = BiNormal.Crossed(DTangent);
}
/*test
Standard_Real h = 1.e-10;
gp_Vec cTangent, cNormal, cBiNormal, Tangent_, Normal_, BiNormal_;
D0(Param, cTangent, cNormal, cBiNormal);
D0(Param + h, Tangent_, Normal_, BiNormal_);
cTangent = (Tangent_ - cTangent)/h;
cNormal = (Normal_ - cNormal)/h;
cBiNormal = (BiNormal_ - cBiNormal)/h;
cout<<"DTangent = ("<<DTangent.X()<<", "<<DTangent.Y()<<", "<<DTangent.Z()<<")"<<endl;
cout<<"CTangent = ("<<cTangent.X()<<", "<<cTangent.Y()<<", "<<cTangent.Z()<<")"<<endl;
cout<<"DNormal = ("<<DNormal.X()<<", "<<DNormal.Y()<<", "<<DNormal.Z()<<")"<<endl;
cout<<"CNormal = ("<<cNormal.X()<<", "<<cNormal.Y()<<", "<<cNormal.Z()<<")"<<endl;
cout<<"DBiNormal = ("<<DBiNormal.X()<<", "<<DBiNormal.Y()<<", "<<DBiNormal.Z()<<")"<<endl;
cout<<"CBiNormal = ("<<cBiNormal.X()<<", "<<cBiNormal.Y()<<", "<<cBiNormal.Z()<<")"<<endl;
*/
return Standard_True;
}
Standard_Boolean GeomFill_ConstantBiNormal::D2(const Standard_Real Param,
gp_Vec& Tangent,
gp_Vec& DTangent,
gp_Vec& D2Tangent,
gp_Vec& Normal,
gp_Vec& DNormal,
gp_Vec& D2Normal,
gp_Vec& BiNormal,
gp_Vec& DBiNormal,
gp_Vec& D2BiNormal)
{
gp_Vec F, DF, D2F;
frenet->D2(Param, Tangent, DTangent, D2Tangent,
Normal, DNormal, D2Normal,
BiNormal, DBiNormal, D2BiNormal);
BiNormal = BN;
DBiNormal = gp_Vec(0, 0, 0);
D2BiNormal = gp_Vec(0, 0, 0);
if(BiNormal.Crossed(Tangent).Magnitude() > Precision::Confusion()) {
F = BiNormal.Crossed(Tangent);
DF = BiNormal.Crossed(DTangent);
D2F = BiNormal.Crossed(D2Tangent);
Normal = F.Normalized();
DNormal = FDeriv(F, DF);
D2Normal = DDeriv(F, DF, D2F);
Tangent = Normal.Crossed(BiNormal);
DTangent = DNormal.Crossed(BiNormal);
D2Tangent = D2Normal.Crossed(BiNormal);
}
else {
F = Normal.Crossed(BiNormal);
DF = DNormal.Crossed(BiNormal);
D2F = D2Normal.Crossed(BiNormal);
Tangent = F.Normalized();
DTangent = FDeriv(F, DF);
D2Tangent = DDeriv(F, DF, D2F);
Normal = BiNormal.Crossed(Tangent);
DNormal = BiNormal.Crossed(DTangent);
D2Normal = BiNormal.Crossed(D2Tangent);
}
/* cout<<"Param = "<<Param<<endl;
cout<<"Tangent = ("<<Tangent.X()<<", "<<Tangent.Y()<<", "<<Tangent.Z()<<")"<<endl;
cout<<"DTangent = ("<<DTangent.X()<<", "<<DTangent.Y()<<", "<<DTangent.Z()<<")"<<endl;
cout<<"D2Tangent = ("<<D2Tangent.X()<<", "<<D2Tangent.Y()<<", "<<D2Tangent.Z()<<")"<<endl;
cout<<"BiNormal = ("<<BiNormal.X()<<", "<<BiNormal.Y()<<", "<<BiNormal.Z()<<")"<<endl;
cout<<"DBiNormal = ("<<DBiNormal.X()<<", "<<DBiNormal.Y()<<", "<<DBiNormal.Z()<<")"<<endl;
cout<<"D2BiNormal = ("<<D2BiNormal.X()<<", "<<D2BiNormal.Y()<<", "<<D2BiNormal.Z()<<")"<<endl;
*/
return Standard_True;
}
Standard_Integer GeomFill_ConstantBiNormal::NbIntervals(const GeomAbs_Shape S) const
{
return frenet->NbIntervals(S);
}
void GeomFill_ConstantBiNormal::Intervals(TColStd_Array1OfReal& T,const GeomAbs_Shape S) const
{
frenet->Intervals(T, S);
}
void GeomFill_ConstantBiNormal::GetAverageLaw(gp_Vec& ATangent,gp_Vec& ANormal,gp_Vec& ABiNormal)
{
frenet->GetAverageLaw(ATangent, ANormal, ABiNormal);
ABiNormal = BN;
if(ABiNormal.Crossed(ATangent).Magnitude() > Precision::Confusion()) {
ANormal = ABiNormal.Crossed(ATangent).Normalized();
ATangent = ANormal.Crossed(ABiNormal);
}
else {
ATangent = ANormal.Crossed(ABiNormal).Normalized();
ANormal = ABiNormal.Crossed(ATangent);
}
}
Standard_Boolean GeomFill_ConstantBiNormal::IsConstant() const
{
return frenet->IsConstant();
}
Standard_Boolean GeomFill_ConstantBiNormal::IsOnlyBy3dCurve() const
{
GeomAbs_CurveType TheType = myCurve->GetType();
gp_Ax1 TheAxe;
switch (TheType) {
case GeomAbs_Circle:
{
TheAxe = myCurve->Circle().Axis();
break;
}
case GeomAbs_Ellipse:
{
TheAxe = myCurve->Ellipse().Axis();
break;
}
case GeomAbs_Hyperbola:
{
TheAxe = myCurve->Hyperbola().Axis();
break;
}
case GeomAbs_Parabola:
{
TheAxe = myCurve->Parabola().Axis();
break;
}
case GeomAbs_Line:
{ //La normale du plan de la courbe est il perpendiculaire a la BiNormale ?
gp_Vec V;
V.SetXYZ(myCurve->Line().Direction().XYZ());
return V.IsNormal(BN, Precision::Angular());
}
default:
return Standard_False; // pas de risques
}
// La normale du plan de la courbe est il // a la BiNormale ?
gp_Vec V;
V.SetXYZ(TheAxe.Direction().XYZ());
return V.IsParallel(BN, Precision::Angular());
}

View File

@@ -0,0 +1,253 @@
-- File: GeomFill_ConstrainedFilling.cdl
-- Created: Fri Oct 13 17:38:33 1995
-- Author: Laurent BOURESCHE
-- <lbo@phylox>
---Copyright: Matra Datavision 1995
class ConstrainedFilling from GeomFill
---Purpose: An algorithm for constructing a BSpline surface filled
-- from a series of boundaries which serve as path
-- constraints and optionally, as tangency constraints.
-- The algorithm accepts three or four curves as the
-- boundaries of the target surface.
-- A ConstrainedFilling object provides a framework for:
-- - defining the boundaries of the surface
-- - implementing the construction algorithm
-- - consulting the result.
-- Warning
-- This surface filling algorithm is specifically designed to
-- be used in connection with fillets. Satisfactory results
-- cannot be guaranteed for other uses.
uses
HArray1OfInteger from TColStd,
HArray1OfReal from TColStd,
Pnt from gp,
Vec from gp,
HArray1OfPnt from TColgp,
HArray2OfPnt from TColgp,
CornerState from GeomFill,
Boundary from GeomFill,
BoundWithSurf from GeomFill,
CoonsAlgPatch from GeomFill,
TgtField from GeomFill,
BSplineSurface from Geom,
Function from Law
is
Create (MaxDeg, MaxSeg : Integer from Standard)
returns ConstrainedFilling from GeomFill;
---Purpose:
-- Constructs an empty framework for filling a surface from boundaries.
-- The boundaries of the surface will be defined, and the
-- surface will be built by using the function Init.
-- The surface will respect the following constraints:
-- - its degree will not be greater than MaxDeg
-- - the maximum number of segments MaxSeg which
-- BSpline surfaces can have.
Init(me : in out;
B1,B2,B3 : Boundary from GeomFill;
NoCheck : Boolean from Standard = Standard_False);
Init(me : in out;
B1,B2,B3,B4 : Boundary from GeomFill;
NoCheck : Boolean from Standard = Standard_False);
---Purpose: Constructs a BSpline surface filled from the series of
-- boundaries B1, B2, B3 and, if need be, B4, which serve:
-- - as path constraints
-- - and optionally, as tangency constraints if they are
-- GeomFill_BoundWithSurf curves.
-- The boundaries may be given in any order: they are
-- classified and if necessary, reversed and reparameterized.
-- The surface will also respect the following constraints:
-- - its degree will not be greater than the maximum
-- degree defined at the time of construction of this framework, and
-- - the maximum number of segments MaxSeg which BSpline surfaces can have
SetDomain(me : in out;
l : Real from Standard;
B : BoundWithSurf from GeomFill);
---Purpose: Allows to modify domain on witch the blending function
-- associated to the constrained boundary B will propag
-- the influence of the field of tangency. Can be
-- usefull to reduce influence of boundaries on whitch
-- the Coons compatibility conditions are not respected.
-- l is a relative value of the parametric range of B.
-- Default value for l is 1 (used in Init).
-- Warning: Must be called after Init with a constrained boundary
-- used in the call to Init.
ReBuild(me : in out)
---Purpose: Computes the new poles of the surface using the new
-- blending functions set by several calls to SetDomain.
is static;
--------------------------------------------------------------------
Boundary(me; I : Integer from Standard)
returns Boundary from GeomFill;
---Purpose: Returns the bound of index i after sort.
Surface(me) returns BSplineSurface from Geom;
---Purpose: Returns the BSpline surface after computation of the fill by this framework.
--------------------------------------------------------------------
--------------------------------------------------------------------
-- Internal use computation functions
--------------------------------------------------------------------
Build(me : in out)
---Purpose: Performs the approximation an compute the poles of the
-- surface.
is static private;
PerformApprox(me : in out)
---Purpose: Performs the parallel approximation on two oppsite
-- bounds
is static private;
MatchKnots(me : in out)
---Purpose: matches the nodal vectors of the blending functions
-- and the results of the approx to allow the surface
-- computation.
is static private;
PerformS0(me : in out)
---Purpose: performs the poles of the partial construction S0.
is static private;
PerformS1(me : in out)
---Purpose: performs the poles of the partial construction S1.
is static private;
PerformSurface(me : in out)
---Purpose: performs the poles of the surface using the partial
-- constructions S0 and S1.
is static private;
CheckTgte(me : in out; I : Integer from Standard)
---Purpose: Checks if the field of tangency doesn t twist along the
-- boundary.
returns Boolean from Standard
is static private;
MinTgte(me : in out; I : Integer from Standard)
---Purpose: Evaluates the min magnitude of the field of tangency
-- along bound I to allow a simple evaluation of the
-- tolerance needed for the approximation of the field of
-- tangency.
is static private;
Eval(me;
W : Real from Standard ;
Ord : Integer from Standard ;
Result : in out Real from Standard)
---Purpose: Internal use for Advmath approximation call.
returns Integer from Standard;
--------------------------------------------------------------------
-- Internal use functions for debug :
-- The graphic traces are compiled only with -D DEB option,
-- can be used only in Draw Appli context.
--------------------------------------------------------------------
CheckCoonsAlgPatch(me : in out; I : Integer from Standard)
---Purpose: Computes the fields of tangents on 30 points along the
-- bound I, these are not the constraint tangents but
-- gives an idea of the coonsAlgPatch regularity.
is static;
CheckTgteField(me : in out; I : Integer from Standard)
---Purpose: Computes the fields of tangents and normals on 30
-- points along the bound I, draw them, and computes the
-- max dot product that must be near than 0.
is static;
CheckApprox(me : in out; I : Integer from Standard)
---Purpose: Computes values and normals along the bound I and
-- compare them to the approx result curves (bound and
-- tgte field) , draw the normals and tangents.
is static;
CheckResult(me : in out; I : Integer from Standard)
---Purpose: Computes values and normals along the bound I on both
-- constraint surface and result surface, draw the
-- normals, and computes the max distance between values
-- and the max angle between normals.
is static;
fields
-- data for approximation.
degmax : Integer from Standard;
segmax : Integer from Standard;
-- the algorithmic patch.
ptch : CoonsAlgPatch from GeomFill;
-- the algorithmic tangents fields
tgalg : TgtField from GeomFill[4];
-- the evaluation of the min of the algorithmic tangents fields
-- magnitude.
mig : Real from Standard [4];
-- data about corners conditionning the existence of solution.
stcor : CornerState from GeomFill [4];
-- the derivatives on corners.
v : Vec from gp [4];
-- result curves of aproximation.
appdone : Boolean from Standard;
tolapp3d : Real from Standard[4];
tolappang : Real from Standard[4];
degree : Integer from Standard [2];
curvpol : HArray1OfPnt from TColgp [4];
tgtepol : HArray1OfPnt from TColgp [4];
mults : HArray1OfInteger from TColStd [2];
knots : HArray1OfReal from TColStd [2];
-- the blending functions for the patial result S0 surface (only
-- bounds)
ab : HArray1OfReal from TColStd [4];
-- the blending functions for the patial result S1 surface
-- (including tangency constraints)
pq : HArray1OfReal from TColStd [4];
dom : Real from Standard [4];
-- new arrays computed in order to match the blending functions
-- nodal vectors and the approximated curves nodal vectors. these
-- data are recomputed at each call to ReBuild method, without any
-- new perform of the approx.
ncpol : HArray1OfPnt from TColgp [4];
ntpol : HArray1OfPnt from TColgp [4];
nm : HArray1OfInteger from TColStd [2];
nk : HArray1OfReal from TColStd [2];
-- nombre de courbes a approximer pour chaque bord ctr[i]
ibound: Integer [2];
ctr : Integer [2];
nbd3 : Integer;
-- partial results of surface poles computed by blending curvpol
-- an tgtepol.
S0 : HArray2OfPnt from TColgp;
S1 : HArray2OfPnt from TColgp;
-- the result surface.
surf : BSplineSurface from Geom;
end ConstrainedFilling;

File diff suppressed because it is too large Load Diff

32
src/GeomFill/GeomFill_Coons.cdl Executable file
View File

@@ -0,0 +1,32 @@
-- File: GeomFill_Coons.cdl
-- Created: Tue Sep 28 16:18:35 1993
-- Author: Bruno DUMORTIER
-- <dub@sdsun1>
---Copyright: Matra Datavision 1993
class Coons from GeomFill inherits Filling from GeomFill
uses
Array1OfPnt from TColgp,
Array1OfReal from TColStd
is
Create;
Create(P1, P2, P3, P4 : Array1OfPnt from TColgp)
returns Coons from GeomFill;
Create(P1, P2, P3, P4 : Array1OfPnt from TColgp;
W1, W2, W3, W4 : Array1OfReal from TColStd)
returns Coons from GeomFill;
Init(me : in out;
P1, P2, P3, P4 : Array1OfPnt from TColgp)
is static;
Init(me : in out;
P1, P2, P3, P4 : Array1OfPnt from TColgp;
W1, W2, W3, W4 : Array1OfReal from TColStd)
is static;
end Coons;

213
src/GeomFill/GeomFill_Coons.cxx Executable file
View File

@@ -0,0 +1,213 @@
// File: GeomFill_Coons.cxx
// Created: Wed Sep 29 10:46:05 1993
// Author: Bruno DUMORTIER
// <dub@sdsun1>
#include <GeomFill_Coons.ixx>
#include <BSplCLib.hxx>
#include <PLib.hxx>
#include <TColgp_HArray2OfPnt.hxx>
#include <TColStd_HArray2OfReal.hxx>
//=======================================================================
//function : GeomFill_Coons
//purpose :
//=======================================================================
GeomFill_Coons::GeomFill_Coons()
{
}
//=======================================================================
//function : GeomFill_Coons
//purpose :
//=======================================================================
GeomFill_Coons::GeomFill_Coons(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2,
const TColgp_Array1OfPnt& P3,
const TColgp_Array1OfPnt& P4)
{
Init( P1, P2, P3, P4);
}
//=======================================================================
//function : GeomFill_Coons
//purpose :
//=======================================================================
GeomFill_Coons::GeomFill_Coons(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2,
const TColgp_Array1OfPnt& P3,
const TColgp_Array1OfPnt& P4,
const TColStd_Array1OfReal& W1,
const TColStd_Array1OfReal& W2,
const TColStd_Array1OfReal& W3,
const TColStd_Array1OfReal& W4)
{
Init( P1, P2, P3, P4, W1, W2, W3, W4);
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_Coons::Init(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2,
const TColgp_Array1OfPnt& P3,
const TColgp_Array1OfPnt& P4)
{
Standard_DomainError_Raise_if
( P1.Length() != P3.Length() || P2.Length() != P4.Length()," ");
Standard_Integer NPolU = P1.Length();
Standard_Integer NPolV = P2.Length();
IsRational = Standard_False;
myPoles = new TColgp_HArray2OfPnt( 1, NPolU, 1, NPolV);
// The boundaries are not modified
Standard_Integer i,j,k;
for (i=1; i<=NPolU; i++) {
myPoles->SetValue( i, 1 , P1(i));
myPoles->SetValue( i, NPolV, P3(i));
}
for (i=1; i<=NPolV; i++) {
myPoles->SetValue( 1 , i, P2(i));
myPoles->SetValue( NPolU, i, P4(i));
}
// Calcul des coefficients multiplicateurs
TColgp_Array1OfPnt Coef ( 1, 4);
TColgp_Array1OfPnt Pole ( 1, 4);
TColgp_Array1OfPnt CoefU( 1, NPolU);
TColgp_Array1OfPnt CoefV( 1, NPolV);
Coef( 4) = gp_Pnt( 2., -2., 0.);
Coef( 3) = gp_Pnt( -3., 3., 0.);
Coef( 2) = gp_Pnt( 0., 0., 0.);
Coef( 1) = gp_Pnt( 1., 0., 0.);
PLib::CoefficientsPoles(Coef, PLib::NoWeights(),
Pole, PLib::NoWeights());
if (NPolU > 4) {
BSplCLib::IncreaseDegree(NPolU-1, Pole, PLib::NoWeights(),
CoefU, PLib::NoWeights());
}
else {
CoefU = Pole;
}
if (NPolV > 4) {
BSplCLib::IncreaseDegree(NPolV-1, Pole, PLib::NoWeights(),
CoefV, PLib::NoWeights());
}
else {
CoefV = Pole;
}
TColStd_Array1OfReal FU(2,NPolU-1);
TColStd_Array1OfReal GU(2,NPolU-1);
TColStd_Array1OfReal FV(2,NPolV-1);
TColStd_Array1OfReal GV(2,NPolV-1);
Standard_Real Dummy;
for ( i= 2; i< NPolU; i++) {
CoefU(i).Coord(FU(i), GU(i), Dummy);
}
for ( i= 2; i< NPolV; i++) {
CoefV(i).Coord(FV(i), GV(i), Dummy);
}
// Clacul des poles interieurs
gp_Pnt P;
for ( j=2; j<NPolV; j++) {
for ( i=2; i<NPolU; i++) {
for ( k=1; k<=3 ; k++) {
P.SetCoord( k,
FV(j) * (myPoles->Value(i ,1 )).Coord(k)
+ GV(j) * (myPoles->Value(i ,NPolV)).Coord(k)
+ FU(i) * (myPoles->Value(1 ,j )).Coord(k)
+ GU(i) * (myPoles->Value(NPolU,j )).Coord(k)
- FU(i) * FV(j) * (myPoles->Value(1 ,1 )).Coord(k)
- FU(i) * GV(j) * (myPoles->Value(1 ,NPolV)).Coord(k)
- GU(i) * FV(j) * (myPoles->Value(NPolU,1 )).Coord(k)
- GU(i) * GV(j) * (myPoles->Value(NPolU,NPolV)).Coord(k));
}
myPoles->SetValue(i,j,P);
}
}
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_Coons::Init(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2,
const TColgp_Array1OfPnt& P3,
const TColgp_Array1OfPnt& P4,
const TColStd_Array1OfReal& W1,
const TColStd_Array1OfReal& W2,
const TColStd_Array1OfReal& W3,
const TColStd_Array1OfReal& W4
)
{
Standard_DomainError_Raise_if
( W1.Length() != W3.Length() || W2.Length() != W4.Length()," ");
Standard_DomainError_Raise_if
( W1.Length() != P1.Length() ||
W2.Length() != P2.Length() ||
W3.Length() != P3.Length() ||
W4.Length() != P4.Length() , " ");
Init(P1,P2,P3,P4);
IsRational = Standard_True;
Standard_Integer NPolU = W1.Length();
Standard_Integer NPolV = W2.Length();
//#ifdef DEB
Standard_Real NU = NPolU - 1;
Standard_Real NV = NPolV - 1;
//#endif
myWeights = new TColStd_HArray2OfReal( 1, NPolU, 1, NPolV);
// The boundaries are not modified
Standard_Integer i,j;
for ( i=1; i<=NPolU; i++) {
myWeights->SetValue( i, 1 , W1(i));
myWeights->SetValue( i, NPolV, W3(i));
}
Standard_Real PU,PU1,PV,PV1;
for ( j=2; j<=NPolV-1; j++) {
PV = (j-1)/NV;
PV1 = 1 - PV;
myWeights->SetValue( 1 , j, W4(j));
myWeights->SetValue( NPolU, j, W2(j));
for ( i=2; i<=NPolU-1; i++) {
PU = (i-1)/NU;
PU1 = 1 - PU;
// Standard_Real W = 0.5 * ( PV1 * W1(i) + PV * W3(i) +
// PU * W2(j) + PU1 * W4(j) );
Standard_Real W = PV1 * W1(i) + PV * W3(i) +
PU * W2(j) + PU1 * W4(j) -
( PU1 * PV1 * W1(1) +
PU * PV1 * W2(1) +
PU * PV * W3(NPolU) +
PU1 * PV * W4(NPolV) );
myWeights->SetValue(i,j,W);
}
}
}

View File

@@ -0,0 +1,96 @@
-- File: GeomFill_CoonsAlgPatch.cdl
-- Created: Mon Dec 4 09:38:55 1995
-- Author: Laurent BOURESCHE
-- <lbo@phylox>
---Copyright: Matra Datavision 1995
class CoonsAlgPatch from GeomFill inherits TShared from MMgt
---Purpose: Provides evaluation methods on an algorithmic
-- patch defined by its boundaries and blending
-- functions.
uses
Pnt from gp,
Vec from gp,
Boundary from GeomFill,
Function from Law
is
Create(B1, B2, B3, B4 : Boundary from GeomFill)
---Purpose: Constructs the algorithmic patch. By Default the
-- constructed blending functions are linear.
-- Warning: No control is done on the bounds.
-- B1/B3 and B2/B4 must be same range and well oriented.
returns mutable CoonsAlgPatch from GeomFill;
Func(me;
f1,f2 : out Function from Law)
---Purpose: Give the blending functions.
is static;
SetFunc(me : mutable;
f1,f2 : Function from Law)
---Purpose: Set the blending functions.
is static;
Value(me;
U,V : Real from Standard) returns Pnt from gp
---Purpose: Computes the value on the algorithmic patch at
-- parameters U and V.
is static;
D1U(me;
U,V : Real from Standard)
returns Vec from gp
---Purpose: Computes the d/dU partial derivative on the
-- algorithmic patch at parameters U and V.
is static;
D1V(me;
U,V : Real from Standard)
returns Vec from gp
---Purpose: Computes the d/dV partial derivative on the
-- algorithmic patch at parameters U and V.
is static;
DUV(me;
U,V : Real from Standard)
returns Vec from gp
---Purpose: Computes the d2/dUdV partial derivative on the
-- algorithmic patch made with linear blending functions
-- at parameter U and V.
is static;
Corner(me; I : Integer from Standard)
---C++: return const&
returns Pnt from gp
is static;
Bound(me; I : Integer from Standard)
---C++: return const&
returns any Boundary from GeomFill
is static;
Func(me; I : Integer from Standard)
---C++: return const&
returns any Function from Law
is static;
fields
-- the boundaries.
bound : Boundary from GeomFill [4];
-- the corners.
c : Pnt from gp [4];
gap : Real from Standard [4];
-- the blending functions.
a : Function from Law [2];
end CoonsAlgPatch;

View File

@@ -0,0 +1,323 @@
// File: GeomFill_CoonsAlgPatch.cxx
// Created: Mon Dec 4 14:41:51 1995
// Author: Laurent BOURESCHE
// <lbo@phylox>
#include <GeomFill_CoonsAlgPatch.ixx>
#include <Law_Linear.hxx>
#include <gp_XYZ.hxx>
//=======================================================================
//function : GeomFill_CoonsAlgPatch
//purpose :
//=======================================================================
GeomFill_CoonsAlgPatch::GeomFill_CoonsAlgPatch
(const Handle(GeomFill_Boundary)& B1,
const Handle(GeomFill_Boundary)& B2,
const Handle(GeomFill_Boundary)& B3,
const Handle(GeomFill_Boundary)& B4)
{
bound[0] = B1; bound[1] = B2; bound[2] = B3; bound[3] = B4;
Standard_Real deb0, deb1, fin0, fin1;
B2->Bounds(deb1,fin1);
a[0] = new Law_Linear();
(*((Handle_Law_Linear*) &a[0]))->Set(deb1,1.,fin1,0.);
B1->Bounds(deb0,fin0);
a[1] = new Law_Linear();
(*((Handle_Law_Linear*) &a[1]))->Set(deb0,0.,fin0,1.);
gp_XYZ temp;
temp = B4->Value(deb1).XYZ().Added(B1->Value(deb0).XYZ());
temp.Multiply(0.5);
c[0].SetXYZ(temp);
temp = B1->Value(fin0).XYZ().Added(B2->Value(deb1).XYZ());
temp.Multiply(0.5);
c[1].SetXYZ(temp);
temp = B2->Value(fin1).XYZ().Added(B3->Value(fin0).XYZ());
temp.Multiply(0.5);
c[2].SetXYZ(temp);
temp = B3->Value(deb0).XYZ().Added(B4->Value(fin1).XYZ());
temp.Multiply(0.5);
c[3].SetXYZ(temp);
}
//=======================================================================
//function : SetFunc
//purpose :
//=======================================================================
void GeomFill_CoonsAlgPatch::SetFunc(const Handle(Law_Function)& f1,
const Handle(Law_Function)& f2)
{
a[0] = f1;
a[1] = f2;
}
//=======================================================================
//function : Func
//purpose :
//=======================================================================
void GeomFill_CoonsAlgPatch::Func(Handle(Law_Function)& f1,
Handle(Law_Function)& f2)const
{
f1 = a[0];
f2 = a[1];
}
//=======================================================================
//function : Value
//purpose :
//=======================================================================
//gp_Pnt GeomFill_CoonsAlgPatch::Value(const Standard_Real U,
gp_Pnt GeomFill_CoonsAlgPatch::Value(const Standard_Real ,
const Standard_Real V) const
{
Standard_Real a0,a1,a2,a3;
a0 = a[0]->Value(V);
a1 = a[1]->Value(V);
a2 = 1. - a0;
a3 = 1. - a1;
gp_XYZ cor,cortemp;
cor = bound[0]->Value(V).XYZ();
cor.Multiply(a0);
cortemp = bound[1]->Value(V).XYZ();
cortemp.Multiply(a1);
cor.Add(cortemp);
cortemp = bound[2]->Value(V).XYZ();
cortemp.Multiply(a2);
cor.Add(cortemp);
cortemp = bound[3]->Value(V).XYZ();
cortemp.Multiply(a3);
cor.Add(cortemp);
cortemp = c[0].XYZ();
cortemp.Multiply(-a0*a3);
cor.Add(cortemp);
cortemp = c[1].XYZ();
cortemp.Multiply(-a0*a1);
cor.Add(cortemp);
cortemp = c[2].XYZ();
cortemp.Multiply(-a1*a2);
cor.Add(cortemp);
cortemp = c[3].XYZ();
cortemp.Multiply(-a2*a3);
cor.Add(cortemp);
return gp_Pnt(cor);
}
//=======================================================================
//function : D1U
//purpose :
//=======================================================================
gp_Vec GeomFill_CoonsAlgPatch::D1U(const Standard_Real U,
const Standard_Real V) const
{
Standard_Real a0,a1,a2,a3,bid;
a0 = a[0]->Value(V);
a[1]->D1(U,bid,a1);
a2 = 1 - a0;
a3 = -a1;
gp_XYZ cor,cortemp;
gp_Pnt pbid;
gp_Vec vbid;
bound[0]->D1(U,pbid,vbid);
cor = vbid.XYZ();
cor.Multiply(a0);
cortemp = bound[1]->Value(V).XYZ();
cortemp.Multiply(a1);
cor.Add(cortemp);
bound[2]->D1(U,pbid,vbid);
cortemp = vbid.XYZ();
cortemp.Multiply(a2);
cor.Add(cortemp);
cortemp = bound[3]->Value(V).XYZ();
cortemp.Multiply(a3);
cor.Add(cortemp);
cortemp = c[0].XYZ();
cortemp.Multiply(-a0*a3);
cor.Add(cortemp);
cortemp = c[1].XYZ();
cortemp.Multiply(-a0*a1);
cor.Add(cortemp);
cortemp = c[2].XYZ();
cortemp.Multiply(-a1*a2);
cor.Add(cortemp);
cortemp = c[3].XYZ();
cortemp.Multiply(-a2*a3);
cor.Add(cortemp);
vbid.SetXYZ(cor);
return vbid;
}
//=======================================================================
//function : D1V
//purpose :
//=======================================================================
gp_Vec GeomFill_CoonsAlgPatch::D1V(const Standard_Real U,
const Standard_Real V) const
{
Standard_Real a0,a1,a2,a3,bid;
a[0]->D1(V,bid,a0);
a1 = a[1]->Value(U);
a2 = -a0;
a3 = 1. - a1;
gp_XYZ cor,cortemp;
gp_Pnt pbid;
gp_Vec vbid;
cor = bound[0]->Value(U).XYZ();
cor.Multiply(a0);
bound[1]->D1(V,pbid,vbid);
cortemp = vbid.XYZ();
cortemp.Multiply(a1);
cor.Add(cortemp);
cortemp = bound[2]->Value(U).XYZ();
cortemp.Multiply(a2);
cor.Add(cortemp);
bound[3]->D1(V,pbid,vbid);
cortemp = vbid.XYZ();
cortemp.Multiply(a3);
cor.Add(cortemp);
cortemp = c[0].XYZ();
cortemp.Multiply(-a0*a3);
cor.Add(cortemp);
cortemp = c[1].XYZ();
cortemp.Multiply(-a0*a1);
cor.Add(cortemp);
cortemp = c[2].XYZ();
cortemp.Multiply(-a1*a2);
cor.Add(cortemp);
cortemp = c[3].XYZ();
cortemp.Multiply(-a2*a3);
cor.Add(cortemp);
vbid.SetXYZ(cor);
return vbid;
}
//=======================================================================
//function : DUV
//purpose :
//=======================================================================
gp_Vec GeomFill_CoonsAlgPatch::DUV(const Standard_Real U,
const Standard_Real V) const
{
Standard_Real a0,a1,a2,a3,bid;
a[0]->D1(V,bid,a0);
a[1]->D1(U,bid,a1);
a2 = -a0;
a3 = -a1;
gp_XYZ cor,cortemp;
gp_Pnt pbid;
gp_Vec vbid;
bound[0]->D1(U,pbid,vbid);
cor = vbid.XYZ();
cor.Multiply(a0);
bound[1]->D1(V,pbid,vbid);
cortemp = vbid.XYZ();
cortemp.Multiply(a1);
cor.Add(cortemp);
bound[2]->D1(U,pbid,vbid);
cortemp = vbid.XYZ();
cortemp.Multiply(a2);
cor.Add(cortemp);
bound[3]->D1(V,pbid,vbid);
cortemp = vbid.XYZ();
cortemp.Multiply(a3);
cor.Add(cortemp);
cortemp = c[0].XYZ();
cortemp.Multiply(-a0*a3);
cor.Add(cortemp);
cortemp = c[1].XYZ();
cortemp.Multiply(-a0*a1);
cor.Add(cortemp);
cortemp = c[2].XYZ();
cortemp.Multiply(-a1*a2);
cor.Add(cortemp);
cortemp = c[3].XYZ();
cortemp.Multiply(-a2*a3);
cor.Add(cortemp);
vbid.SetXYZ(cor);
return vbid;
}
//=======================================================================
//function : Bound
//purpose :
//=======================================================================
const Handle(GeomFill_Boundary)& GeomFill_CoonsAlgPatch::Bound
(const Standard_Integer I) const
{
return bound[I];
}
//=======================================================================
//function : Corner
//purpose :
//=======================================================================
const gp_Pnt& GeomFill_CoonsAlgPatch::Corner(const Standard_Integer I) const
{
return c[I];
}
//=======================================================================
//function : Func
//purpose :
//=======================================================================
const Handle(Law_Function)& GeomFill_CoonsAlgPatch::Func
(const Standard_Integer I)const
{
return a[I];
}

View File

@@ -0,0 +1,39 @@
-- File: GeomFill_CornerState.cdl
-- Created: Fri Dec 8 10:00:47 1995
-- Author: Laurent BOURESCHE
-- <lbo@phylox>
---Copyright: Matra Datavision 1995
class CornerState from GeomFill
---Purpose: Class (should be a structure) storing the
-- informations about continuity, normals
-- parallelism, coons conditions and bounds tangents
-- angle on the corner of contour to be filled.
is
Create returns CornerState from GeomFill;
Gap(me) returns Real from Standard;
Gap(me : in out; G : Real from Standard);
TgtAng(me) returns Real from Standard;
TgtAng(me : in out; Ang : Real from Standard);
HasConstraint(me) returns Boolean from Standard;
Constraint(me : in out);
NorAng(me) returns Real from Standard;
NorAng(me : in out; Ang : Real from Standard);
IsToKill(me; Scal : out Real from Standard)
returns Boolean from Standard;
DoKill(me : in out; Scal : Real from Standard);
fields
gap : Real from Standard;
tgtang : Real from Standard;
isconstrained : Boolean from Standard;
norang : Real from Standard;
scal : Real from Standard;
coonscnd : Boolean from Standard;
end CornerState;

View File

@@ -0,0 +1,134 @@
// File: GeomFill_CornerState.cxx
// Created: Fri Dec 8 16:26:44 1995
// Author: Laurent BOURESCHE
// <lbo@phylox>
#include <GeomFill_CornerState.ixx>
//=======================================================================
//function : GeomFill_CornerState
//purpose :
//=======================================================================
GeomFill_CornerState::GeomFill_CornerState() :
gap(RealLast()),
isconstrained(0),
scal(1.),
coonscnd(1)
{
}
//=======================================================================
//function : Gap
//purpose :
//=======================================================================
Standard_Real GeomFill_CornerState::Gap() const
{
return gap;
}
//=======================================================================
//function : Gap
//purpose :
//=======================================================================
void GeomFill_CornerState::Gap(const Standard_Real G)
{
gap = G;
}
//=======================================================================
//function : TgtAng
//purpose :
//=======================================================================
Standard_Real GeomFill_CornerState::TgtAng() const
{
return tgtang;
}
//=======================================================================
//function : TgtAng
//purpose :
//=======================================================================
void GeomFill_CornerState::TgtAng(const Standard_Real Ang)
{
tgtang = Ang;
}
//=======================================================================
//function : HasConstraint
//purpose :
//=======================================================================
Standard_Boolean GeomFill_CornerState::HasConstraint() const
{
return isconstrained;
}
//=======================================================================
//function : Constraint
//purpose :
//=======================================================================
void GeomFill_CornerState::Constraint()
{
isconstrained = 1;
}
//=======================================================================
//function : NorAng
//purpose :
//=======================================================================
Standard_Real GeomFill_CornerState::NorAng() const
{
return norang;
}
//=======================================================================
//function : NorAng
//purpose :
//=======================================================================
void GeomFill_CornerState::NorAng(const Standard_Real Ang)
{
norang = Ang;
}
//=======================================================================
//function : IsToKill
//purpose :
//=======================================================================
Standard_Boolean GeomFill_CornerState::IsToKill(Standard_Real& Scal) const
{
Scal = scal;
if(!isconstrained) return 0;
return !coonscnd;
}
//=======================================================================
//function : DoKill
//purpose :
//=======================================================================
void GeomFill_CornerState::DoKill(const Standard_Real Scal)
{
scal = Scal;
coonscnd = 0;
}

View File

@@ -0,0 +1,164 @@
-- File: GeomFill_CorrectedFrenet.cdl
-- Created: Fri Dec 19 11:57:52 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
class CorrectedFrenet from GeomFill
inherits TrihedronLaw from GeomFill
---Purpose: Defined an Corrected Frenet Trihedron Law It is
-- like Frenet with an Torsion's minimization
uses
Frenet from GeomFill,
HCurve from Adaptor3d,
Shape from GeomAbs,
Array1OfReal from TColStd,
Function from Law,
Vec from gp,
---OCC78
HArray1OfReal from TColStd,
SequenceOfReal from TColStd,
HArray1OfVec from TColgp,
SequenceOfVec from TColgp
raises
OutOfRange, ConstructionError
is
Create returns CorrectedFrenet from GeomFill;
Copy(me)
returns TrihedronLaw from GeomFill
is redefined;
Init(me: mutable)
is static private;
InitInterval(me; First, Last, Step: Real;
startAng: in out Real;
prevTangent, prevNormal, aT, aN: out Vec from gp;
FuncInt: out Function from Law;
SeqPoles: out SequenceOfReal from TColStd;
SeqAngle: out SequenceOfReal from TColStd;
SeqTangent: out SequenceOfVec from TColgp;
SeqNormal: out SequenceOfVec from TColgp)
returns Boolean
--- Purpose: Computes BSpline representation of Normal evolution at one
--- interval of continuity of Frenet. Returns True if FuncInt = 0
is private;
--- OCC78
CalcAngleAT(me; Tangent, Normal, prevTangent, prevNormal: in Vec from gp)
returns Real
--- Purpose: Computes angle of Normal evolution of Frenet between any two points on the curve.
is private;
GetAngleAT(me; P: in Real)
returns Real
--- Purpose: Get corrected value of angle of Normal evolution of Frenet
is private;
SetCurve(me : mutable; C : HCurve from Adaptor3d)
is redefined;
SetInterval(me: mutable; First, Last: Real)
is redefined;
--
--
--========== To compute Location and derivatives Location
--
D0(me : mutable;
Param: Real;
Tangent : out Vec from gp;
Normal : out Vec from gp;
BiNormal : out Vec from gp)
---Purpose: compute Triedrhon on curve at parameter <Param>
returns Boolean is redefined;
D1(me : mutable;
Param: Real;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp)
---Purpose: compute Triedrhon and derivative Trihedron on curve
-- at parameter <Param>
-- Warning : It used only for C1 or C2 aproximation
returns Boolean
is redefined;
D2(me : mutable;
Param: Real;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
D2Tangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
D2Normal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp;
D2BiNormal : out Vec from gp)
---Purpose: compute Trihedron on curve
-- first and seconde derivatives.
-- Warning : It used only for C2 aproximation
returns Boolean
is redefined;
--
-- =================== Management of continuity ===================
--
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>.
-- May be one if Continuity(me) >= <S>
returns Integer is redefined;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is redefined;
-- =================== To help computation of Tolerance ===============
GetAverageLaw(me : mutable;
ATangent : out Vec from gp;
ANormal : out Vec from gp;
ABiNormal : out Vec from gp)
---Purpose: Get average value of Tangent(t) and Normal(t) it is usfull to
-- make fast approximation of rational surfaces.
is redefined;
-- =================== To help Particular case ===============
IsConstant(me)
---Purpose: Say if the law is Constant.
returns Boolean
is redefined;
IsOnlyBy3dCurve(me)
---Purpose: Return True.
returns Boolean
is redefined;
fields
frenet : Frenet from GeomFill;
EvolAroundT : Function from Law;
TLaw : Function from Law;
AT, AN : Vec from gp;
isFrenet : Boolean;
---OCC78
HArrPoles : HArray1OfReal from TColStd;
HArrAngle : HArray1OfReal from TColStd;
HArrTangent : HArray1OfVec from TColgp;
HArrNormal : HArray1OfVec from TColgp;
end CorrectedFrenet;

View File

@@ -0,0 +1,911 @@
// File: GeomFill_CorrectedFrenet.cxx
// Created: Fri Dec 19 13:25:12 1997
// Author: Roman BORISOV /Philippe MANGIN
// <pmn@sgi29>
#include <stdio.h>
#include <GeomFill_CorrectedFrenet.ixx>
#include <GeomAbs_CurveType.hxx>
#include <Adaptor3d_HCurve.hxx>
#include <gp_Trsf.hxx>
#include <Precision.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <Law_Interpolate.hxx>
#include <TColStd_SequenceOfReal.hxx>
#include <gp_Vec2d.hxx>
#include <BndLib_Add3dCurve.hxx>
#include <Bnd_Box.hxx>
#include <GeomLib.hxx>
#include <Law_Composite.hxx>
#include <Law_Constant.hxx>
#include <Law_BSpFunc.hxx>
#include <Law_BSpline.hxx>
#include <GeomFill_SnglrFunc.hxx>
//Patch
#include <Geom_Plane.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_BSplineCurve.hxx>
#include <TColgp_HArray1OfPnt.hxx>
#ifdef DEB
static Standard_Boolean Affich=0;
#endif
#ifdef DRAW
static Standard_Integer CorrNumber = 0;
#include <Draw_Appli.hxx>
#include <DrawTrSurf.hxx>
#include <Draw_Segment2D.hxx>
//#include <Draw.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_HArray1OfInteger.hxx>
#endif
#ifdef DRAW
static void draw(const Handle(Law_Function)& law)
{
Standard_Real Step, u, v, tmin;
Standard_Integer NbInt, i, j, jmax;
NbInt = law->NbIntervals(GeomAbs_C3);
TColStd_Array1OfReal Int(1, NbInt+1);
law->Intervals(Int, GeomAbs_C3);
gp_Pnt2d old;
Handle(Draw_Segment2D) tg2d;
for(i = 1; i <= NbInt; i++){
tmin = Int(i);
Step = (Int(i+1)-Int(i))/4;
if (i == NbInt) jmax = 4;
else jmax = 3;
for (j=1; j<=jmax; j++) {
u = tmin + (j-1)*Step;
v = law->Value(u);
gp_Pnt2d point2d(u,v);
if ((i>1)||(j>1)) {
tg2d = new Draw_Segment2D(old, point2d,Draw_kaki);
dout << tg2d;
}
old = point2d;
}
}
dout.Flush();
}
#endif
//===============================================================
// Function : smoothlaw
// Purpose : to smooth a law : Reduce the number of knots
//===============================================================
static void smoothlaw(Handle(Law_BSpline)& Law,
const Handle(TColStd_HArray1OfReal)& Points,
const Handle(TColStd_HArray1OfReal)& Param,
const Standard_Real Tol)
{
Standard_Real tol, d;
Standard_Integer ii, Nbk;
Standard_Boolean B, Ok;
Handle(Law_BSpline) BS = Law->Copy();
Nbk = BS->NbKnots();
tol = Tol/10;
Ok = Standard_False;
for (ii=Nbk-1; ii>1; ii--) { // Une premiere passe tolerance serres
B = BS->RemoveKnot(ii, 0, tol);
if (B) Ok = Standard_True;
}
if (Ok) { // controle
tol = 0.;
for (ii=1; ii<=Param->Length() && Ok; ii++) {
d = Abs(BS->Value(Param->Value(ii))-Points->Value(ii));
if (d > tol) tol = d;
Ok = (tol <= Tol);
}
if (Ok)
tol = (Tol-tol)/2;
else {
#if DEB
cout << "smooth law echec" << endl;
#endif
return; // Echec
}
}
else {
tol = Tol/2;
}
if (Ok) Law = BS;
Ok = Standard_False; // Une deuxieme passe tolerance desserre
Nbk = BS->NbKnots();
for (ii=Nbk-1; ii>1; ii--) {
B = BS->RemoveKnot(ii, 0, tol);
if (B) Ok = Standard_True;
}
if (Ok) { // controle
tol = 0.;
for (ii=1; ii<=Param->Length() && Ok; ii++) {
d = Abs(BS->Value(Param->Value(ii))-Points->Value(ii));
if (d > tol) tol = d;
Ok = (tol <= Tol);
}
if (!Ok) {
#if DEB
cout << "smooth law echec" << endl;
#endif
}
}
if (Ok) Law = BS;
#if DEB
if (Affich) {
cout << "Knots Law : " << endl;
for (ii=1; ii<=BS->NbKnots(); ii++) {
cout << ii << " : " << BS->Knot(ii) << endl;
}
}
#endif
}
//===============================================================
// Function : FindPlane
// Purpose :
//===============================================================
static Standard_Boolean FindPlane ( const Handle(Adaptor3d_HCurve)& c,
Handle( Geom_Plane )& P )
{
Standard_Boolean found = Standard_True;
Handle(TColgp_HArray1OfPnt) TabP;
switch (c->GetType()) {
case GeomAbs_Line:
{
found = Standard_False;
}
break;
case GeomAbs_Circle:
P = new Geom_Plane(gp_Ax3(c->Circle().Position()));
break;
case GeomAbs_Ellipse:
P = new Geom_Plane(gp_Ax3(c->Ellipse().Position()));
break;
case GeomAbs_Hyperbola:
P = new Geom_Plane(gp_Ax3(c->Hyperbola().Position()));
break;
case GeomAbs_Parabola:
P = new Geom_Plane(gp_Ax3(c->Parabola().Position()));
break;
case GeomAbs_BezierCurve:
{
Handle(Geom_BezierCurve) GC = c->Bezier();
Standard_Integer nbp = GC->NbPoles();
if ( nbp < 2)
found = Standard_False;
else if ( nbp == 2) {
found = Standard_False;
}
else {
TabP = new (TColgp_HArray1OfPnt) (1, nbp);
GC->Poles(TabP->ChangeArray1());
}
}
break;
case GeomAbs_BSplineCurve:
{
Handle(Geom_BSplineCurve) GC = c->BSpline();
Standard_Integer nbp = GC->NbPoles();
if ( nbp < 2)
found = Standard_False;
else if ( nbp == 2) {
found = Standard_False;
}
else {
TabP = new (TColgp_HArray1OfPnt) (1, nbp);
GC->Poles(TabP->ChangeArray1());
}
}
break;
default:
{ // On utilise un echantillonage
Standard_Integer nbp = 15 + c->NbIntervals(GeomAbs_C3);
Standard_Real f, l, t, inv;
Standard_Integer ii;
f = c->FirstParameter();
l = c->LastParameter();
inv = 1./(nbp-1);
for (ii=1; ii<=nbp; ii++) {
t = ( f*(nbp-ii) + l*(ii-1));
t *= inv;
TabP->SetValue(ii, c->Value(t));
}
}
}
if (! TabP.IsNull()) { // Recherche d'un plan moyen et controle
Standard_Boolean issingular;
gp_Ax2 inertia;
GeomLib::AxeOfInertia(TabP->Array1(), inertia, issingular);
if (issingular) {
found = Standard_False;
}
else {
P = new Geom_Plane(inertia);
}
if (found)
{
//control = Controle(TabP->Array1(), P, myTolerance);
// Standard_Boolean isOnPlane;
Standard_Real a,b,c,d, dist;
Standard_Integer ii;
P->Coefficients(a,b,c,d);
for (ii=1; ii<=TabP->Length() && found; ii++) {
const gp_XYZ& xyz = TabP->Value(ii).XYZ();
dist = a*xyz.X() + b*xyz.Y() + c*xyz.Z() + d;
found = (Abs(dist) <= Precision::Confusion());
}
return found;
}
}
return found;
}
//===============================================================
// Function :
// Purpose :
//===============================================================
GeomFill_CorrectedFrenet::GeomFill_CorrectedFrenet()
: isFrenet(Standard_False)
{
frenet = new GeomFill_Frenet();
}
Handle(GeomFill_TrihedronLaw) GeomFill_CorrectedFrenet::Copy() const
{
Handle(GeomFill_CorrectedFrenet) copy = new (GeomFill_CorrectedFrenet)();
if (!myCurve.IsNull()) copy->SetCurve(myCurve);
return copy;
}
void GeomFill_CorrectedFrenet::SetCurve(const Handle(Adaptor3d_HCurve)& C)
{
GeomFill_TrihedronLaw::SetCurve(C);
if (! C.IsNull()) {
frenet->SetCurve(C);
GeomAbs_CurveType type;
type = C->GetType();
switch (type) {
case GeomAbs_Circle:
case GeomAbs_Ellipse:
case GeomAbs_Hyperbola:
case GeomAbs_Parabola:
case GeomAbs_Line:
{
// No probleme isFrenet
isFrenet = Standard_True;
}
default :
{
// We have to search singulaties
isFrenet = Standard_True;
Init();
}
}
}
}
//===============================================================
// Function : Init
// Purpose : Compute angle's law
//===============================================================
void GeomFill_CorrectedFrenet::Init()
{
EvolAroundT = new Law_Composite();
Standard_Integer NbI = frenet->NbIntervals(GeomAbs_C0), i;
TColStd_Array1OfReal T(1, NbI + 1);
frenet->Intervals(T, GeomAbs_C0);
Handle(Law_Function) Func;
//OCC78
TColStd_SequenceOfReal SeqPoles, SeqAngle;
TColgp_SequenceOfVec SeqTangent, SeqNormal;
gp_Vec Tangent, Normal, BN;
frenet->D0(myTrimmed->FirstParameter(), Tangent, Normal, BN);
Standard_Integer NbStep;
// Standard_Real StartAng = 0, AvStep, Step, t;
Standard_Real StartAng = 0, AvStep, Step;
#if DRAW
Standard_Real t;
if (Affich) { // Display the curve C'^C''(t)
GeomFill_SnglrFunc CS(myCurve);
NbStep = 99;
AvStep = (myTrimmed->LastParameter() -
myTrimmed->FirstParameter())/NbStep;
TColgp_Array1OfPnt TabP(1, NbStep+1);
TColStd_Array1OfReal TI(1, NbStep+1);
TColStd_Array1OfInteger M(1,NbStep+1);
M.Init(1);
M(1) = M(NbStep+1) = 2;
for (i=1; i<=NbStep+1; i++) {
t = (myTrimmed->FirstParameter()+ (i-1)*AvStep);
CS.D0(t, TabP(i));
TI(i) = t;
}
char tname[100];
Standard_CString name = tname ;
sprintf(name,"Binorm_%d", ++CorrNumber);
Handle(Geom_BSplineCurve) BS = new
(Geom_BSplineCurve) (TabP, TI, M, 1);
// DrawTrSurf::Set(&name[0], BS);
DrawTrSurf::Set(name, BS);
}
#endif
NbStep = 10;
AvStep = (myTrimmed->LastParameter() - myTrimmed->FirstParameter())/NbStep;
for(i = 1; i <= NbI; i++) {
NbStep = Max(Standard_Integer((T(i+1) - T(i))/AvStep), 3);
Step = (T(i+1) - T(i))/NbStep;
if(!InitInterval(T(i), T(i+1), Step, StartAng, Tangent, Normal, AT, AN, Func, SeqPoles, SeqAngle, SeqTangent, SeqNormal))
if(isFrenet) isFrenet = Standard_False;
Handle(Law_Composite)::DownCast(EvolAroundT)->ChangeLaws().Append(Func);
}
if(myTrimmed->IsPeriodic())
Handle(Law_Composite)::DownCast(EvolAroundT)->SetPeriodic();
TLaw = EvolAroundT;
//OCC78
Standard_Integer iEnd = SeqPoles.Length();
HArrPoles = new TColStd_HArray1OfReal(1, iEnd);
HArrAngle = new TColStd_HArray1OfReal(1, iEnd);
HArrTangent = new TColgp_HArray1OfVec(1, iEnd);
HArrNormal = new TColgp_HArray1OfVec(1, iEnd);
for(i = 1; i <= iEnd; i++){
HArrPoles->ChangeValue(i) = SeqPoles(i);
HArrAngle->ChangeValue(i) = SeqAngle(i);
HArrTangent->ChangeValue(i) = SeqTangent(i);
HArrNormal->ChangeValue(i) = SeqNormal(i);
};
#if DRAW
if (Affich) {
draw(EvolAroundT);
}
#endif
}
//===============================================================
// Function : InitInterval
// Purpose : Compute the angle law on a span
//===============================================================
Standard_Boolean GeomFill_CorrectedFrenet::
InitInterval(const Standard_Real First, const Standard_Real Last,
const Standard_Real Step,
Standard_Real& startAng, gp_Vec& prevTangent,
gp_Vec& prevNormal, gp_Vec& aT, gp_Vec& aN,
Handle(Law_Function)& FuncInt,
TColStd_SequenceOfReal& SeqPoles,
TColStd_SequenceOfReal& SeqAngle,
TColgp_SequenceOfVec& SeqTangent,
TColgp_SequenceOfVec& SeqNormal) const
{
Bnd_Box Boite;
gp_Vec Tangent, Normal, BN, cross;
TColStd_SequenceOfReal parameters;
TColStd_SequenceOfReal EvolAT;
Standard_Real Param = First, LengthMin, L, norm;
Standard_Boolean isZero = Standard_True, isConst = Standard_True;
Standard_Integer i;
gp_Pnt PonC;
gp_Vec D1;
frenet->SetInterval(First, Last); //To have the rigth evaluation at bounds
GeomFill_SnglrFunc CS(myCurve);
BndLib_Add3dCurve::Add(CS, First, Last, 1.e-2, Boite);
LengthMin = Boite.GetGap()*1.e-4;
aT = gp_Vec(0, 0, 0);
aN = gp_Vec(0, 0, 0);
Standard_Real angleAT, currParam, currStep = Step;
Handle( Geom_Plane ) aPlane;
Standard_Boolean isPlanar = FindPlane( myCurve, aPlane );
i = 1;
currParam = Param;
Standard_Real DLast = Last - Precision::PConfusion();
while (Param < Last) {
if (currParam > DLast) {
currStep = DLast - Param;
currParam = Last;
}
if (isPlanar)
currParam = Last;
frenet->D0(currParam, Tangent, Normal, BN);
if (prevTangent.Angle(Tangent) < PI/3 || i == 1) {
parameters.Append(currParam);
//OCC78
SeqPoles.Append(Param);
SeqAngle.Append(i > 1? EvolAT(i-1) : startAng);
SeqTangent.Append(prevTangent);
SeqNormal.Append(prevNormal);
angleAT = CalcAngleAT(Tangent,Normal,prevTangent,prevNormal);
if(isConst && i > 1)
if(Abs(angleAT) > Precision::PConfusion())
isConst = Standard_False;
angleAT += (i > 1) ? EvolAT(i-1) : startAng;
EvolAT.Append(angleAT);
prevNormal = Normal;
if(isZero)
if(Abs(angleAT) > Precision::PConfusion())
isZero = Standard_False;
aT += Tangent;
cross = Tangent.Crossed(Normal);
aN.SetLinearForm(Sin(angleAT), cross,
1 - Cos(angleAT), Tangent.Crossed(cross),
Normal+aN);
prevTangent = Tangent;
Param = currParam;
i++;
//Evaluate the Next step
CS.D1(Param, PonC, D1);
L = Max(PonC.XYZ().Modulus()/2, LengthMin);
norm = D1.Magnitude();
if (norm < Precision::Confusion()) {
norm = Precision::Confusion();
}
currStep = L / norm;
if (currStep > Step) currStep = Step;//default value
}
else
currStep /= 2; // Step too long !
currParam = Param + currStep;
}
if (! isPlanar)
{
aT /= parameters.Length() - 1;
aN /= parameters.Length() - 1;
}
startAng = angleAT;
// Interpolation
if (isConst || isPlanar) {
FuncInt = new Law_Constant();
Handle(Law_Constant)::DownCast(FuncInt)->Set( angleAT, First, Last );
}
else {
Standard_Integer Length = parameters.Length();
Handle(TColStd_HArray1OfReal) pararr =
new TColStd_HArray1OfReal(1, Length);
Handle(TColStd_HArray1OfReal) angleATarr =
new TColStd_HArray1OfReal(1, Length);
for (i = 1; i <= Length; i++) {
pararr->ChangeValue(i) = parameters(i);
angleATarr->ChangeValue(i) = EvolAT(i);
}
#if DEB
if (Affich) {
cout<<"NormalEvolution"<<endl;
for (i = 1; i <= Length; i++) {
cout<<"("<<pararr->Value(i)<<", "<<angleATarr->Value(i)<<")" << endl;
}
cout<<endl;
}
#endif
Law_Interpolate lawAT(angleATarr, pararr,
Standard_False, Precision::PConfusion());
lawAT.Perform();
Handle(Law_BSpline) BS = lawAT.Curve();
smoothlaw(BS, angleATarr, pararr, 0.1);
FuncInt = new Law_BSpFunc(BS, First, Last);
}
return isZero;
}
//===============================================================
// Function : CalcAngleAT (OCC78)
// Purpose : Calculate angle of rotation of trihedron normal and its derivatives relative
// at any position on his curve
//===============================================================
Standard_Real GeomFill_CorrectedFrenet::CalcAngleAT(const gp_Vec& Tangent, const gp_Vec& Normal,
const gp_Vec& prevTangent, const gp_Vec& prevNormal) const
{
Standard_Real angle;
gp_Vec Normal_rot, cross;
angle = Tangent.Angle(prevTangent);
if (Abs(angle) > Precision::Angular()) {
cross = Tangent.Crossed(prevTangent).Normalized();
Normal_rot = Normal + sin(angle)*cross.Crossed(Normal) +
(1 - cos(angle))*cross.Crossed(cross.Crossed(Normal));
}
else
Normal_rot = Normal;
Standard_Real angleAT = Normal_rot.Angle(prevNormal);
if(angleAT > Precision::Angular() && PI - angleAT > Precision::Angular())
if (Normal_rot.Crossed(prevNormal).IsOpposite(prevTangent, Precision::Angular()))
angleAT = -angleAT;
return angleAT;
};
//===============================================================
// Function : ... (OCC78)
// Purpose : This family of functions produce conversion of angle utility
//===============================================================
static Standard_Real corrPI_2PI(Standard_Real Ang){
return Ang = (Ang >= 0.0? Ang: 2*PI+Ang);
};
static Standard_Real corr2PI_PI(Standard_Real Ang){
return Ang = (Ang < PI? Ang: Ang-2*PI);
};
static Standard_Real diffAng(Standard_Real A, Standard_Real Ao){
Standard_Real dA = (A-Ao) - Floor((A-Ao)/2.0/PI)*2.0*PI;
return dA = dA >= 0? corr2PI_PI(dA): -corr2PI_PI(-dA);
};
//===============================================================
// Function : CalcAngleAT (OCC78)
// Purpose : Calculate angle of rotation of trihedron normal and its derivatives relative
// at any position on his curve
//===============================================================
Standard_Real GeomFill_CorrectedFrenet::GetAngleAT(const Standard_Real Param) const{
// Search index of low margin from poles of TLaw by bisection method
Standard_Integer iB = 1, iE = HArrPoles->Length(), iC = (iE+iB)/2;
if(Param == HArrPoles->Value(iB)) return TLaw->Value(Param);
if(Param > HArrPoles->Value(iE)) iC = iE;
if(iC < iE){
while(!(HArrPoles->Value(iC) <= Param && Param <= HArrPoles->Value(iC+1))){
if(HArrPoles->Value(iC) < Param) iB = iC; else iE = iC;
iC = (iE+iB)/2;
};
if(HArrPoles->Value(iC) == Param || Param == HArrPoles->Value(iC+1)) return TLaw->Value(Param);
};
#ifdef DEB
Standard_Real Po =
#endif
HArrPoles->Value(iC);
// Calculate differenciation between apporoximated and local values of AngleAT
Standard_Real AngP = TLaw->Value(Param), AngPo = HArrAngle->Value(iC), dAng = AngP - AngPo;
gp_Vec Tangent, Normal, BN;
frenet->D0(Param, Tangent, Normal, BN);
Standard_Real DAng = CalcAngleAT(Tangent, Normal, HArrTangent->Value(iC), HArrNormal->Value(iC));
Standard_Real DA = diffAng(DAng,dAng);
// The correction (there is core of OCC78 bug)
if(Abs(DA) > PI/2.0){
AngP = AngPo + DAng;
};
return AngP;
};
//===============================================================
// Function : D0
// Purpose :
//===============================================================
Standard_Boolean GeomFill_CorrectedFrenet::D0(const Standard_Real Param,
gp_Vec& Tangent,
gp_Vec& Normal,
gp_Vec& BiNormal)
{
frenet->D0(Param, Tangent, Normal, BiNormal);
if (isFrenet) return Standard_True;
Standard_Real angleAT;
//angleAT = TLaw->Value(Param);
angleAT = GetAngleAT(Param); //OCC78
// rotation around Tangent
gp_Vec cross;
cross = Tangent.Crossed(Normal);
Normal.SetLinearForm(Sin(angleAT), cross,
(1 - Cos(angleAT)), Tangent.Crossed(cross),
Normal);
BiNormal = Tangent.Crossed(Normal);
return Standard_True;
}
//===============================================================
// Function : D1
// Purpose :
//===============================================================
Standard_Boolean GeomFill_CorrectedFrenet::D1(const Standard_Real Param,
gp_Vec& Tangent,
gp_Vec& DTangent,
gp_Vec& Normal,
gp_Vec& DNormal,
gp_Vec& BiNormal,
gp_Vec& DBiNormal)
{
frenet->D1(Param, Tangent, DTangent, Normal, DNormal, BiNormal, DBiNormal);
if (isFrenet) return Standard_True;
Standard_Real angleAT, d_angleAT;
Standard_Real sina, cosa;
TLaw->D1(Param, angleAT, d_angleAT);
angleAT = GetAngleAT(Param); //OCC78
gp_Vec cross, dcross, tcross, dtcross, aux;
sina = Sin(angleAT);
cosa = Cos(angleAT);
cross = Tangent.Crossed(Normal);
dcross.SetLinearForm(1, DTangent.Crossed(Normal),
Tangent.Crossed(DNormal));
tcross = Tangent.Crossed(cross);
dtcross.SetLinearForm(1, DTangent.Crossed(cross),
Tangent.Crossed(dcross));
aux.SetLinearForm(sina, dcross,
cosa*d_angleAT, cross);
aux.SetLinearForm(1 - cosa, dtcross,
sina*d_angleAT, tcross,
aux);
DNormal+=aux;
Normal.SetLinearForm( sina, cross,
(1 - cosa), tcross,
Normal);
BiNormal = Tangent.Crossed(Normal);
DBiNormal.SetLinearForm(1, DTangent.Crossed(Normal),
Tangent.Crossed(DNormal));
// for test
/* gp_Vec FDN, Tf, Nf, BNf;
Standard_Real h;
h = 1.0e-8;
if (Param + h > myTrimmed->LastParameter()) h = -h;
D0(Param + h, Tf, Nf, BNf);
FDN = (Nf - Normal)/h;
cout<<"Param = "<<Param<<endl;
cout<<"DN = ("<<DNormal.X()<<", "<<DNormal.Y()<<", "<<DNormal.Z()<<")"<<endl;
cout<<"FDN = ("<<FDN.X()<<", "<<FDN.Y()<<", "<<FDN.Z()<<")"<<endl;
*/
return Standard_True;
}
//===============================================================
// Function : D2
// Purpose :
//===============================================================
Standard_Boolean GeomFill_CorrectedFrenet::D2(const Standard_Real Param,
gp_Vec& Tangent,
gp_Vec& DTangent,
gp_Vec& D2Tangent,
gp_Vec& Normal,
gp_Vec& DNormal,
gp_Vec& D2Normal,
gp_Vec& BiNormal,
gp_Vec& DBiNormal,
gp_Vec& D2BiNormal)
{
frenet->D2(Param, Tangent, DTangent, D2Tangent,
Normal, DNormal, D2Normal,
BiNormal, DBiNormal, D2BiNormal);
if (isFrenet) return Standard_True;
Standard_Real angleAT, d_angleAT, d2_angleAT;
Standard_Real sina, cosa;
TLaw->D2(Param, angleAT, d_angleAT, d2_angleAT);
angleAT = GetAngleAT(Param); //OCC78
gp_Vec cross, dcross, d2cross, tcross, dtcross, d2tcross, aux;
sina = Sin(angleAT);
cosa = Cos(angleAT);
cross = Tangent.Crossed(Normal);
dcross.SetLinearForm(1, DTangent.Crossed(Normal),
Tangent.Crossed(DNormal));
d2cross.SetLinearForm(1, D2Tangent.Crossed(Normal),
2, DTangent.Crossed(DNormal),
Tangent.Crossed(D2Normal));
tcross = Tangent.Crossed(cross);
dtcross.SetLinearForm(1, DTangent.Crossed(cross),
Tangent.Crossed(dcross));
d2tcross.SetLinearForm(1, D2Tangent.Crossed(cross),
2, DTangent.Crossed(dcross),
Tangent.Crossed(d2cross));
aux.SetLinearForm(sina, d2cross,
2*cosa*d_angleAT, dcross,
cosa*d2_angleAT - sina*d_angleAT*d_angleAT, cross);
aux.SetLinearForm(1 - cosa, d2tcross,
2*sina*d_angleAT, dtcross,
cosa*d_angleAT*d_angleAT + sina*d2_angleAT, tcross,
aux);
D2Normal += aux;
/* D2Normal += sina*(D2Tangent.Crossed(Normal) + 2*DTangent.Crossed(DNormal) + Tangent.Crossed(D2Normal)) +
2*cosa*d_angleAT*(DTangent.Crossed(Normal) + Tangent.Crossed(DNormal)) +
(cosa*d2_angleAT - sina*d_angleAT*d_angleAT)*Tangent.Crossed(Normal) +
2*sina*d_angleAT*(DTangent.Crossed(Tangent.Crossed(Normal)) + Tangent.Crossed(DTangent.Crossed(Normal)) + Tangent.Crossed(Tangent.Crossed(DNormal))) +
(1 - cosa)*(D2Tangent.Crossed(Tangent.Crossed(Normal)) + Tangent.Crossed(D2Tangent.Crossed(Normal)) + Tangent.Crossed(Tangent.Crossed(D2Normal)) + 2*DTangent.Crossed(DTangent.Crossed(Normal)) + 2*DTangent.Crossed(Tangent.Crossed(DNormal)) + 2*Tangent.Crossed(DTangent.Crossed(DNormal)))
+
(cosa*d_angleAT*d_angleAT + sina*d2_angleAT)*Tangent.Crossed(Tangent.Crossed(Normal));*/
aux.SetLinearForm(sina, dcross,
cosa*d_angleAT, cross);
aux.SetLinearForm(1 - cosa, dtcross,
sina*d_angleAT, tcross,
aux);
DNormal+=aux;
Normal.SetLinearForm( sina, cross,
(1 - cosa), tcross,
Normal);
BiNormal = Tangent.Crossed(Normal);
DBiNormal.SetLinearForm(1, DTangent.Crossed(Normal),
Tangent.Crossed(DNormal));
D2BiNormal.SetLinearForm(1, D2Tangent.Crossed(Normal),
2, DTangent.Crossed(DNormal),
Tangent.Crossed(D2Normal));
// for test
/* gp_Vec FD2N, FD2T, FD2BN, Tf, DTf, Nf, DNf, BNf, DBNf;
Standard_Real h;
h = 1.0e-8;
if (Param + h > myTrimmed->LastParameter()) h = -h;
D1(Param + h, Tf, DTf, Nf, DNf, BNf, DBNf);
FD2N = (DNf - DNormal)/h;
FD2T = (DTf - DTangent)/h;
FD2BN = (DBNf - DBiNormal)/h;
cout<<"Param = "<<Param<<endl;
cout<<"D2N = ("<<D2Normal.X()<<", "<<D2Normal.Y()<<", "<<D2Normal.Z()<<")"<<endl;
cout<<"FD2N = ("<<FD2N.X()<<", "<<FD2N.Y()<<", "<<FD2N.Z()<<")"<<endl<<endl;
cout<<"D2T = ("<<D2Tangent.X()<<", "<<D2Tangent.Y()<<", "<<D2Tangent.Z()<<")"<<endl;
cout<<"FD2T = ("<<FD2T.X()<<", "<<FD2T.Y()<<", "<<FD2T.Z()<<")"<<endl<<endl;
cout<<"D2BN = ("<<D2BiNormal.X()<<", "<<D2BiNormal.Y()<<", "<<D2BiNormal.Z()<<")"<<endl;
cout<<"FD2BN = ("<<FD2BN.X()<<", "<<FD2BN.Y()<<", "<<FD2BN.Z()<<")"<<endl<<endl;
*/
//
return Standard_True;
}
//===============================================================
// Function : NbIntervals
// Purpose :
//===============================================================
Standard_Integer GeomFill_CorrectedFrenet::NbIntervals(const GeomAbs_Shape S) const
{
Standard_Integer NbFrenet, NbLaw;
NbFrenet = frenet->NbIntervals(S);
if (isFrenet) return NbFrenet;
NbLaw = EvolAroundT->NbIntervals(S);
if (NbFrenet == 1)
return NbLaw;
TColStd_Array1OfReal FrenetInt(1, NbFrenet + 1);
TColStd_Array1OfReal LawInt(1, NbLaw + 1);
TColStd_SequenceOfReal Fusion;
frenet->Intervals(FrenetInt, S);
EvolAroundT->Intervals(LawInt, S);
GeomLib::FuseIntervals(FrenetInt, LawInt, Fusion);
return Fusion.Length()-1;
}
//===============================================================
// Function : Intervals
// Purpose :
//===============================================================
void GeomFill_CorrectedFrenet::Intervals(TColStd_Array1OfReal& T,
const GeomAbs_Shape S) const
{
Standard_Integer NbFrenet, NbLaw;
if (isFrenet) {
frenet->Intervals(T, S);
return;
}
NbFrenet = frenet->NbIntervals(S);
if(NbFrenet==1) {
EvolAroundT->Intervals(T, S);
}
NbLaw = EvolAroundT->NbIntervals(S);
TColStd_Array1OfReal FrenetInt(1, NbFrenet + 1);
TColStd_Array1OfReal LawInt(1, NbLaw + 1);
TColStd_SequenceOfReal Fusion;
frenet->Intervals(FrenetInt, S);
EvolAroundT->Intervals(LawInt, S);
GeomLib::FuseIntervals(FrenetInt, LawInt, Fusion);
for(Standard_Integer i = 1; i <= Fusion.Length(); i++)
T.ChangeValue(i) = Fusion.Value(i);
}
//===============================================================
// Function : SetInterval
// Purpose :
//===============================================================
void GeomFill_CorrectedFrenet::SetInterval(const Standard_Real First,
const Standard_Real Last)
{
GeomFill_TrihedronLaw::SetInterval(First, Last);
frenet->SetInterval(First, Last);
if (!isFrenet) TLaw = EvolAroundT->Trim(First, Last,
Precision::PConfusion()/2);
}
//===============================================================
// Function : GetAverageLaw
// Purpose :
//===============================================================
void GeomFill_CorrectedFrenet::GetAverageLaw(gp_Vec& ATangent,
gp_Vec& ANormal,
gp_Vec& ABiNormal)
{
if (isFrenet) frenet->GetAverageLaw(ATangent, ANormal, ABiNormal);
else {
ATangent = AT;
ANormal = AN;
ABiNormal = ATangent;
ABiNormal.Cross(ANormal);
}
}
//===============================================================
// Function : IsConstant
// Purpose :
//===============================================================
Standard_Boolean GeomFill_CorrectedFrenet::IsConstant() const
{
return (myCurve->GetType() == GeomAbs_Line);
}
//===============================================================
// Function : IsOnlyBy3dCurve
// Purpose :
//===============================================================
Standard_Boolean GeomFill_CorrectedFrenet::IsOnlyBy3dCurve() const
{
return Standard_True;
}

View File

@@ -0,0 +1,205 @@
-- File: GeomFill_CurveAndTrihedron.cdl
-- Created: Tue Dec 2 11:51:44 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
class CurveAndTrihedron from GeomFill
inherits LocationLaw from GeomFill
---Purpose: Define location law with an TrihedronLaw and an
-- curve
-- Definition Location is :
-- transformed section coordinates in (Curve(v)),
-- (Normal(v), BiNormal(v), Tangente(v))) systeme are
-- the same like section shape coordinates in
-- (O,(OX, OY, OZ)) systeme.
uses
TrihedronLaw from GeomFill,
HCurve from Adaptor3d,
Mat from gp,
Vec from gp,
Pnt from gp,
Array1OfReal from TColStd,
Array1OfPnt2d from TColgp,
Array1OfVec2d from TColgp,
Shape from GeomAbs
raises OutOfRange
is
Create(Trihedron : TrihedronLaw from GeomFill)
returns CurveAndTrihedron from GeomFill;
SetCurve(me : mutable; C : HCurve from Adaptor3d)
is redefined;
GetCurve(me)
returns HCurve from Adaptor3d
---C++: return const &
is redefined;
SetTrsf(me : mutable; Transfo : Mat from gp)
---Purpose: Set a transformation Matrix like the law M(t) become
-- Mat * M(t)
is redefined;
Copy(me)
returns LocationLaw from GeomFill
is redefined;
--
--========== To compute Location and derivatives Location
--
D0(me : mutable;
Param: Real;
M : out Mat from gp;
V : out Vec from gp)
---Purpose: compute Location and 2d points
returns Boolean is redefined;
D0(me : mutable;
Param: Real;
M : out Mat from gp;
V : out Vec from gp;
Poles2d : out Array1OfPnt2d from TColgp)
---Purpose: compute Location and 2d points
returns Boolean is redefined;
D1(me : mutable;
Param: Real;
M : out Mat from gp;
V : out Vec from gp;
DM : out Mat from gp;
DV : out Vec from gp;
Poles2d : out Array1OfPnt2d from TColgp;
DPoles2d : out Array1OfVec2d from TColgp)
---Purpose: compute location 2d points and associated
-- first derivatives.
-- Warning : It used only for C1 or C2 aproximation
returns Boolean
is redefined;
D2(me : mutable;
Param: Real;
M : out Mat from gp;
V : out Vec from gp;
DM : out Mat from gp;
DV : out Vec from gp;
D2M : out Mat from gp;
D2V : out Vec from gp;
Poles2d : out Array1OfPnt2d from TColgp;
DPoles2d : out Array1OfVec2d from TColgp;
D2Poles2d : out Array1OfVec2d from TColgp)
---Purpose: compute location 2d points and associated
-- first and seconde derivatives.
-- Warning : It used only for C2 aproximation
returns Boolean
is redefined;
--
-- =================== Management of continuity ===================
--
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>.
-- May be one if Continuity(me) >= <S>
returns Integer is redefined;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is redefined;
SetInterval(me: mutable; First, Last: Real from Standard)
---Purpose: Sets the bounds of the parametric interval on
-- the function
-- This determines the derivatives in these values if the
-- function is not Cn.
is redefined;
GetInterval(me; First, Last: out Real from Standard)
---Purpose: Gets the bounds of the parametric interval on
-- the function
is redefined;
GetDomain(me; First, Last: out Real from Standard)
---Purpose: Gets the bounds of the function parametric domain.
-- Warning: This domain it is not modified by the
-- SetValue method
is redefined;
-- =================== To help computation of Tolerance ===============
--
-- Evaluation of error, in 2d space, or on composed function, is
-- difficult. The following methods can help the approximation to
-- make good evaluation and use good tolerances.
--
-- It is not necessary for the following informations to be very
-- precise. A fast evaluation is sufficient.
GetMaximalNorm(me : mutable)
---Purpose: Get the maximum Norm of the matrix-location part. It
-- is usful to find an good Tolerance to approx M(t).
returns Real
is redefined;
GetAverageLaw(me : mutable;
AM: out Mat from gp;
AV: out Vec from gp)
---Purpose: Get average value of M(t) and V(t) it is usfull to
-- make fast approximation of rational surfaces.
is redefined;
--
-- To find elementary sweep
--
IsTranslation(me; Error : out Real)
---Purpose: Say if the Location Law, is an translation of Location
-- The default implementation is " returns False ".
returns Boolean
is redefined;
IsRotation(me; Error : out Real )
---Purpose: Say if the Location Law, is a rotation of Location
-- The default implementation is " returns False ".
returns Boolean
is redefined;
Rotation(me; Center : out Pnt from gp)
is redefined;
fields
WithTrans: Boolean from Standard;
myLaw : TrihedronLaw from GeomFill;
myCurve : HCurve from Adaptor3d;
myTrimmed: HCurve from Adaptor3d;
Point : Pnt from gp;
V1, V2, V3 : Vec from gp;
Trans : Mat from gp;
end CurveAndTrihedron;

View File

@@ -0,0 +1,351 @@
// File: GeomFill_CurveAndTrihedron.cxx
// Created: Fri Dec 5 18:02:16 1997
// Author: Philippe MANGIN
// <pmn@sgi29>
#include <GeomFill_CurveAndTrihedron.ixx>
#include <GeomLib.hxx>
#include <gp_Circ.hxx>
#include <TColStd_SequenceOfReal.hxx>
#include <Precision.hxx>
//==================================================================
//Function: Create
//Purpose :
//==================================================================
GeomFill_CurveAndTrihedron::GeomFill_CurveAndTrihedron(
const Handle(GeomFill_TrihedronLaw)& Trihedron )
{
myLaw = Trihedron;
myCurve.Nullify();
Trans.SetIdentity();
WithTrans = Standard_False;
}
//==================================================================
//Function: Copy
//Purpose :
//==================================================================
Handle(GeomFill_LocationLaw) GeomFill_CurveAndTrihedron::Copy() const
{
Handle(GeomFill_TrihedronLaw) law;
law = myLaw->Copy();
Handle(GeomFill_CurveAndTrihedron) copy =
new (GeomFill_CurveAndTrihedron) (myLaw->Copy());
copy->SetCurve(myCurve);
copy->SetTrsf(Trans);
return copy;
}
//==================================================================
//Function: SetCurve
//Purpose :
//==================================================================
void GeomFill_CurveAndTrihedron::SetCurve(const Handle(Adaptor3d_HCurve)& C)
{
myCurve = C;
myTrimmed = C;
myLaw->SetCurve(C);
}
const Handle(Adaptor3d_HCurve)& GeomFill_CurveAndTrihedron::GetCurve() const
{
return myCurve;
}
//==================================================================
//Function: SetTrsf
//Purpose :
//==================================================================
void GeomFill_CurveAndTrihedron::SetTrsf(const gp_Mat& Transfo)
{
Trans = Transfo;
gp_Mat Aux;
Aux.SetIdentity();
Aux -= Trans;
WithTrans = Standard_False; // Au cas ou Trans = I
for (Standard_Integer ii=1; ii<=3 && !WithTrans ; ii++)
for (Standard_Integer jj=1; jj<=3 && !WithTrans; jj++)
if (Abs(Aux.Value(ii, jj)) > 1.e-14) WithTrans = Standard_True;
}
//==================================================================
//Function: D0
//Purpose :
//==================================================================
Standard_Boolean GeomFill_CurveAndTrihedron::D0(const Standard_Real Param,
gp_Mat& M,
gp_Vec& V)
{
Standard_Boolean Ok;
myTrimmed->D0(Param, Point);
V.SetXYZ(Point.XYZ());
Ok = myLaw->D0(Param, V1, V2, V3);
M.SetCols(V2.XYZ(), V3.XYZ(), V1.XYZ());
if (WithTrans) {
M *= Trans;
}
return Ok;
}
//==================================================================
//Function: D0
//Purpose :
//==================================================================
Standard_Boolean GeomFill_CurveAndTrihedron::D0(const Standard_Real Param,
gp_Mat& M,
gp_Vec& V,
TColgp_Array1OfPnt2d&)
{
Standard_Boolean Ok;
myTrimmed->D0(Param, Point);
V.SetXYZ(Point.XYZ());
Ok = myLaw->D0(Param, V1, V2, V3);
M.SetCols(V2.XYZ(), V3.XYZ(), V1.XYZ());
if (WithTrans) {
M *= Trans;
}
return Ok;
}
//==================================================================
//Function:
//Purpose :
//==================================================================
Standard_Boolean GeomFill_CurveAndTrihedron::D1(const Standard_Real Param,
gp_Mat& M,
gp_Vec& V,
gp_Mat& DM,
gp_Vec& DV,
TColgp_Array1OfPnt2d& ,
TColgp_Array1OfVec2d& )
{
Standard_Boolean Ok;
myTrimmed->D1(Param, Point, DV);
V.SetXYZ(Point.XYZ());
gp_Vec DV1, DV2, DV3;
Ok = myLaw->D1(Param,
V1, DV1,
V2, DV2,
V3, DV3);
M.SetCols( V2.XYZ(), V3.XYZ(), V1.XYZ());
DM.SetCols(DV2.XYZ(), DV3.XYZ(), DV1.XYZ());
if (WithTrans) {
M *= Trans;
DM *= Trans;
}
return Ok;
}
//==================================================================
//Function:
//Purpose :
//==================================================================
Standard_Boolean GeomFill_CurveAndTrihedron::D2(const Standard_Real Param,
gp_Mat& M,
gp_Vec& V,
gp_Mat& DM,
gp_Vec& DV,
gp_Mat& D2M,
gp_Vec& D2V,
TColgp_Array1OfPnt2d&,
TColgp_Array1OfVec2d&,
TColgp_Array1OfVec2d&)
{
Standard_Boolean Ok;
myTrimmed->D2(Param, Point, DV, D2V);
V.SetXYZ(Point.XYZ());
gp_Vec DV1, DV2, DV3;
gp_Vec D2V1, D2V2, D2V3;
Ok = myLaw->D2(Param,
V1, DV1, D2V1,
V2,DV2, D2V2,
V3, DV3, D2V3);
M. SetCols(V2.XYZ(), V3.XYZ(), V1.XYZ());
DM. SetCols(DV2.XYZ(), DV3.XYZ(), DV1.XYZ());
D2M.SetCols(D2V2.XYZ(), D2V3.XYZ(), D2V1.XYZ());
if (WithTrans) {
M *= Trans;
DM *= Trans;
D2M *= Trans;
}
return Ok;
}
//==================================================================
//Function:
//Purpose :
//==================================================================
Standard_Integer GeomFill_CurveAndTrihedron::NbIntervals(const GeomAbs_Shape S) const
{
Standard_Integer Nb_Sec, Nb_Law;
Nb_Sec = myTrimmed->NbIntervals(S);
Nb_Law = myLaw->NbIntervals(S);
if (Nb_Sec==1) {
return Nb_Law;
}
else if (Nb_Law==1) {
return Nb_Sec;
}
TColStd_Array1OfReal IntC(1, Nb_Sec+1);
TColStd_Array1OfReal IntL(1, Nb_Law+1);
TColStd_SequenceOfReal Inter;
myTrimmed->Intervals(IntC, S);
myLaw->Intervals(IntL, S);
GeomLib::FuseIntervals( IntC, IntL, Inter, Precision::PConfusion()*0.99);
return Inter.Length()-1;
}
//==================================================================
//Function:
//Purpose :
//==================================================================
void GeomFill_CurveAndTrihedron::Intervals(TColStd_Array1OfReal& T,
const GeomAbs_Shape S) const
{
Standard_Integer Nb_Sec, Nb_Law;
Nb_Sec = myTrimmed->NbIntervals(S);
Nb_Law = myLaw->NbIntervals(S);
if (Nb_Sec==1) {
myLaw->Intervals(T, S);
return;
}
else if (Nb_Law==1) {
myTrimmed->Intervals(T, S);
return;
}
TColStd_Array1OfReal IntC(1, Nb_Sec+1);
TColStd_Array1OfReal IntL(1, Nb_Law+1);
TColStd_SequenceOfReal Inter;
myTrimmed->Intervals(IntC, S);
myLaw->Intervals(IntL, S);
GeomLib::FuseIntervals(IntC, IntL, Inter, Precision::PConfusion()*0.99);
for (Standard_Integer ii=1; ii<=Inter.Length(); ii++)
T(ii) = Inter(ii);
}
//==================================================================
//Function:
//Purpose :
//==================================================================
void GeomFill_CurveAndTrihedron::SetInterval(const Standard_Real First,
const Standard_Real Last)
{
myLaw->SetInterval( First, Last);
myTrimmed = myCurve->Trim( First, Last, 0);
}
//==================================================================
//Function: GetInterval
//Purpose :
//==================================================================
void GeomFill_CurveAndTrihedron::GetInterval(Standard_Real& First,
Standard_Real& Last) const
{
First = myTrimmed->FirstParameter();
Last = myTrimmed->LastParameter();
}
//==================================================================
//Function: GetDomain
//Purpose :
//==================================================================
void GeomFill_CurveAndTrihedron::GetDomain(Standard_Real& First,
Standard_Real& Last) const
{
First = myCurve->FirstParameter();
Last = myCurve->LastParameter();
}
//==================================================================
//Function:
//Purpose : GetMaximalNorm
// On suppose les triedre normee => return 1
//==================================================================
Standard_Real GeomFill_CurveAndTrihedron::GetMaximalNorm()
{
return 1.;
}
//==================================================================
//Function:
//Purpose :
//==================================================================
void GeomFill_CurveAndTrihedron::GetAverageLaw(gp_Mat& AM,
gp_Vec& AV)
{
Standard_Integer ii;
Standard_Real U, delta;
gp_Vec V;
myLaw->GetAverageLaw(V1, V2, V3);
AM.SetCols(V1.XYZ(), V2.XYZ(), V3.XYZ());
AV.SetCoord(0., 0., 0.);
delta = (myTrimmed->LastParameter() - myTrimmed->FirstParameter())/10;
U= myTrimmed->FirstParameter();
for (ii=0; ii<=10; ii++, U+=delta) {
V.SetXYZ( myTrimmed->Value(U).XYZ() );
AV += V;
}
AV /= 11;
}
//==================================================================
//Function : IsTranslation
//Purpose :
//==================================================================
Standard_Boolean GeomFill_CurveAndTrihedron::IsTranslation(Standard_Real& Error) const
{
GeomAbs_CurveType Type;
Error = 0;
Type = myCurve->GetType();
if (Type == GeomAbs_Line) {
return (myLaw->IsConstant() || myLaw->IsOnlyBy3dCurve());
}
return Standard_False;
}
//==================================================================
//Function : IsRotation
//Purpose :
//==================================================================
Standard_Boolean GeomFill_CurveAndTrihedron::IsRotation(Standard_Real& Error) const
{
GeomAbs_CurveType Type;
Error = 0;
Type = myCurve->GetType();
if (Type == GeomAbs_Circle) {
return myLaw->IsOnlyBy3dCurve();
}
return Standard_False;
}
//==================================================================
//Function : Rotation
//Purpose :
//==================================================================
void GeomFill_CurveAndTrihedron::Rotation(gp_Pnt& Centre) const
{
// GeomAbs_CurveType Type;
// Type = myCurve->GetType();
Centre = myCurve->Circle().Location();
}

View File

@@ -0,0 +1,67 @@
-- File: GeomFill_Curved.cdl
-- Created: Tue Sep 28 16:24:04 1993
-- Author: Bruno DUMORTIER
-- <dub@sdsun1>
---Copyright: Matra Datavision 1993
class Curved from GeomFill inherits Filling from GeomFill
uses
Array1OfPnt from TColgp,
Array1OfReal from TColStd
is
Create;
Create(P1, P2, P3, P4 : Array1OfPnt from TColgp)
returns Curved from GeomFill;
Create(P1, P2, P3, P4 : Array1OfPnt from TColgp;
W1, W2, W3, W4 : Array1OfReal from TColStd)
returns Curved from GeomFill;
Create(P1, P2, P3 : Array1OfPnt from TColgp)
returns Curved from GeomFill;
Create(P1, P2, P3 : Array1OfPnt from TColgp;
W1, W2, W3 : Array1OfReal from TColStd)
returns Curved from GeomFill;
Create(P1, P2 : Array1OfPnt from TColgp)
returns Curved from GeomFill;
Create(P1, P2 : Array1OfPnt from TColgp;
W1, W2 : Array1OfReal from TColStd)
returns Curved from GeomFill;
Init(me : in out;
P1, P2, P3, P4 : Array1OfPnt from TColgp)
is static;
Init(me : in out;
P1, P2, P3, P4 : Array1OfPnt from TColgp;
W1, W2, W3, W4 : Array1OfReal from TColStd)
is static;
Init(me : in out;
P1, P2, P3 : Array1OfPnt from TColgp)
is static;
Init(me : in out;
P1, P2, P3 : Array1OfPnt from TColgp;
W1, W2, W3 : Array1OfReal from TColStd)
is static;
Init(me : in out;
P1, P2 : Array1OfPnt from TColgp)
is static;
Init(me : in out;
P1, P2 : Array1OfPnt from TColgp;
W1, W2 : Array1OfReal from TColStd)
is static;
end Curved;

312
src/GeomFill/GeomFill_Curved.cxx Executable file
View File

@@ -0,0 +1,312 @@
// File: GeomFill_Curved.cxx
// Created: Tue Sep 28 17:58:37 1993
// Author: Bruno DUMORTIER
// <dub@sdsun1>
#include <GeomFill_Curved.ixx>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColgp_HArray2OfPnt.hxx>
#include <TColStd_HArray2OfReal.hxx>
#include <Standard_NotImplemented.hxx>
//=======================================================================
//function : GeomFill_Curved
//purpose :
//=======================================================================
GeomFill_Curved::GeomFill_Curved()
{
}
//=======================================================================
//function : GeomFill_Curved
//purpose :
//=======================================================================
GeomFill_Curved::GeomFill_Curved(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2,
const TColgp_Array1OfPnt& P3,
const TColgp_Array1OfPnt& P4)
{
Init(P1, P2, P3, P4);
}
//=======================================================================
//function : GeomFill_Curved
//purpose :
//=======================================================================
GeomFill_Curved::GeomFill_Curved(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2,
const TColgp_Array1OfPnt& P3,
const TColgp_Array1OfPnt& P4,
const TColStd_Array1OfReal& W1,
const TColStd_Array1OfReal& W2,
const TColStd_Array1OfReal& W3,
const TColStd_Array1OfReal& W4)
{
Init(P1, P2, P3, P4, W1, W2, W3, W4);
}
//=======================================================================
//function : GeomFill_Curved
//purpose :
//=======================================================================
GeomFill_Curved::GeomFill_Curved(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2,
const TColgp_Array1OfPnt& P3)
{
Init(P1, P2, P3);
}
//=======================================================================
//function : GeomFill_Curved
//purpose :
//=======================================================================
GeomFill_Curved::GeomFill_Curved(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2,
const TColgp_Array1OfPnt& P3,
const TColStd_Array1OfReal& W1,
const TColStd_Array1OfReal& W2,
const TColStd_Array1OfReal& W3)
{
Init(P1, P2, P3, W1, W2, W3);
}
//=======================================================================
//function : GeomFill_Curved
//purpose :
//=======================================================================
GeomFill_Curved::GeomFill_Curved(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2)
{
Init(P1, P2);
}
//=======================================================================
//function : GeomFill_Curved
//purpose :
//=======================================================================
GeomFill_Curved::GeomFill_Curved(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2,
const TColStd_Array1OfReal& W1,
const TColStd_Array1OfReal& W2)
{
Init(P1, P2, W1, W2);
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_Curved::Init(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2,
const TColgp_Array1OfPnt& P3,
const TColgp_Array1OfPnt& P4)
{
Standard_DomainError_Raise_if
( P1.Length() != P3.Length() || P2.Length() != P4.Length()," ");
Standard_Integer NPolU = P1.Length();
Standard_Integer NPolV = P2.Length();
IsRational = Standard_False;
Standard_Real NU = NPolU - 1;
Standard_Real NV = NPolV - 1;
myPoles = new TColgp_HArray2OfPnt( 1, NPolU, 1, NPolV);
// The boundaries are not modified
Standard_Integer i,j,k;
for ( i=1; i<=NPolU; i++) {
myPoles->SetValue( i, 1 , P1(i));
myPoles->SetValue( i, NPolV, P3(i));
}
Standard_Real PU,PU1,PV,PV1;
for ( j=2; j<=NPolV-1; j++) {
PV = (j-1)/NV;
PV1 = 1 - PV;
PV /= 2.;
PV1 /= 2.;
myPoles->SetValue( 1 , j, P4(j));
myPoles->SetValue( NPolU, j, P2(j));
for ( i=2; i<=NPolU-1; i++) {
PU = (i-1)/NU;
PU1 = 1 - PU;
PU /= 2.;
PU1 /= 2.;
gp_Pnt P;
for (k=1; k<=3; k++) {
P.SetCoord(k,
PV1 * P1(i).Coord(k) + PV * P3(i).Coord(k) +
PU * P2(j).Coord(k) + PU1 * P4(j).Coord(k) );
}
myPoles->SetValue(i,j,P);
}
}
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_Curved::Init(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2,
const TColgp_Array1OfPnt& P3,
const TColgp_Array1OfPnt& P4,
const TColStd_Array1OfReal& W1,
const TColStd_Array1OfReal& W2,
const TColStd_Array1OfReal& W3,
const TColStd_Array1OfReal& W4)
{
Standard_DomainError_Raise_if
( W1.Length() != W3.Length() || W2.Length() != W4.Length()," ");
Standard_DomainError_Raise_if
( W1.Length() != P1.Length() ||
W2.Length() != P2.Length() ||
W3.Length() != P3.Length() ||
W4.Length() != P4.Length() , " ");
Init(P1,P2,P3,P4);
IsRational = Standard_True;
Standard_Integer NPolU = W1.Length();
Standard_Integer NPolV = W2.Length();
Standard_Real NU = NPolU - 1;
Standard_Real NV = NPolV - 1;
myWeights = new TColStd_HArray2OfReal( 1, NPolU, 1, NPolV);
// The boundaries are not modified
Standard_Integer i,j;
for ( i=1; i<=NPolU; i++) {
myWeights->SetValue( i, 1 , W1(i));
myWeights->SetValue( i, NPolV, W3(i));
}
Standard_Real PU,PU1,PV,PV1;
for ( j=2; j<=NPolV-1; j++) {
PV = (j-1)/NV;
PV1 = 1 - PV;
PV /= 2.;
PV1 /= 2.;
myWeights->SetValue( 1 , j, W4(j));
myWeights->SetValue( NPolU, j, W2(j));
for ( i=2; i<=NPolU-1; i++) {
PU = (i-1)/NU;
PU1 = 1 - PU;
PU /= 2.;
PU1 /= 2.;
Standard_Real W = PV1 * W1(i) + PV * W3(i) +
PU * W2(j) + PU1 * W4(j) ;
myWeights->SetValue(i,j,W);
}
}
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_Curved::Init(const TColgp_Array1OfPnt& , // P1,
const TColgp_Array1OfPnt& , // P2,
const TColgp_Array1OfPnt& )// P3)
{
Standard_NotImplemented::Raise(" ");
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_Curved::Init(const TColgp_Array1OfPnt& , // P1,
const TColgp_Array1OfPnt& , // P2,
const TColgp_Array1OfPnt& , // P3,
const TColStd_Array1OfReal& , // W1,
const TColStd_Array1OfReal& , // W2,
const TColStd_Array1OfReal& ) // W3)
{
Standard_NotImplemented::Raise(" ");
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_Curved::Init(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2)
{
Standard_Integer NPolU = P1.Length();
Standard_Integer NPolV = P2.Length();
IsRational = Standard_False;
#ifdef DEB
Standard_Real NU = NPolU - 1;
Standard_Real NV = NPolV - 1;
#endif
myPoles = new TColgp_HArray2OfPnt( 1, NPolU, 1, NPolV);
Standard_Integer i,j;
for ( j=1; j<=NPolV; j++) {
gp_Vec Tra(P2(1),P2(j));
for ( i=1; i<=NPolU; i++) {
myPoles->SetValue( i, j, P1(i).Translated(Tra));
}
}
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_Curved::Init(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2,
const TColStd_Array1OfReal& W1,
const TColStd_Array1OfReal& W2)
{
Init(P1,P2);
IsRational = Standard_True;
//Initialisation des poids.
Standard_Integer NPolU = W1.Length();
Standard_Integer NPolV = W2.Length();
myWeights = new TColStd_HArray2OfReal( 1, NPolU, 1, NPolV);
for (Standard_Integer j=1; j<=NPolV; j++) {
Standard_Real Factor = W2(j)/W1(1);
for (Standard_Integer i=1; i<=NPolU; i++) {
myWeights->SetValue(i,j,W1(i)*Factor);
}
}
}

118
src/GeomFill/GeomFill_Darboux.cdl Executable file
View File

@@ -0,0 +1,118 @@
-- File: GeomFill_Darboux.cdl
-- Created: Wed Mar 4 11:57:03 1998
-- Author: Roman BORISOV
-- <rbv@ecolox.nnov.matra-dtv.fr>
---Copyright: Matra Datavision 1998
class Darboux from GeomFill
inherits TrihedronLaw from GeomFill
---Purpose: Defines Darboux case of Frenet Trihedron Law
uses
HSurface from Adaptor3d,
Shape from GeomAbs,
Array1OfReal from TColStd,
Vec from gp,
HArray1OfReal from TColStd,
CurveOnSurface from Adaptor3d
raises
OutOfRange, ConstructionError
is
Create
returns Darboux from GeomFill
raises ConstructionError;
Copy(me)
returns TrihedronLaw from GeomFill
is redefined;
--
--
--========== To compute Location and derivatives Location
--
D0(me : mutable;
Param: Real;
Tangent : out Vec from gp;
Normal : out Vec from gp;
BiNormal : out Vec from gp)
---Purpose: compute Triedrhon on curve at parameter <Param>
returns Boolean is redefined;
D1(me : mutable;
Param: Real;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp)
---Purpose: compute Triedrhon and derivative Trihedron on curve
-- at parameter <Param>
-- Warning : It used only for C1 or C2 aproximation
returns Boolean
is redefined;
D2(me : mutable;
Param: Real;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
D2Tangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
D2Normal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp;
D2BiNormal : out Vec from gp)
---Purpose: compute Trihedron on curve
-- first and seconde derivatives.
-- Warning : It used only for C2 aproximation
returns Boolean
is redefined;
--
-- =================== Management of continuity ===================
--
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>.
-- May be one if Continuity(me) >= <S>
returns Integer is redefined;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is redefined;
-- =================== To help computation of Tolerance ===============
GetAverageLaw(me : mutable;
ATangent : out Vec from gp;
ANormal : out Vec from gp;
ABiNormal : out Vec from gp)
---Purpose: Get average value of Tangent(t) and Normal(t) it is usfull to
-- make fast approximation of rational surfaces.
is redefined;
-- =================== To help Particular case ===============
IsConstant(me)
---Purpose: Say if the law is Constant.
returns Boolean
is redefined;
IsOnlyBy3dCurve(me)
---Purpose: Return False.
returns Boolean
is redefined;
end Darboux;

424
src/GeomFill/GeomFill_Darboux.cxx Executable file
View File

@@ -0,0 +1,424 @@
// File: GeomFill_Darboux.cxx
// Created: Wed Mar 4 12:49:02 1998
// Author: Roman BORISOV
// <rbv@ecolox.nnov.matra-dtv.fr>
#include <GeomFill_Darboux.ixx>
#include <Adaptor3d_HCurve.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec2d.hxx>
#include <Adaptor2d_HCurve2d.hxx>
#include <Adaptor3d_CurveOnSurface.hxx>
#include <Adaptor3d_HCurveOnSurface.hxx>
#include <Adaptor3d_HSurface.hxx>
#include <Adaptor3d_CurveOnSurfacePtr.hxx>
#include <CSLib.hxx>
#include <TColgp_Array2OfVec.hxx>
#include <Geom_UndefinedValue.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <GeomAdaptor_Surface.hxx>
//=======================================================================
//function : FDeriv
//purpose : computes (F/|F|)'
//=======================================================================
static gp_Vec FDeriv(const gp_Vec& F, const gp_Vec& DF)
{
Standard_Real Norma = F.Magnitude();
gp_Vec Result = (DF - F*(F*DF)/(Norma*Norma))/Norma;
return Result;
}
//=======================================================================
//function : DDeriv
//purpose : computes (F/|F|)''
//=======================================================================
static gp_Vec DDeriv(const gp_Vec& F, const gp_Vec& DF, const gp_Vec& D2F)
{
Standard_Real Norma = F.Magnitude();
gp_Vec Result = (D2F - 2*DF*(F*DF)/(Norma*Norma))/Norma -
F*((DF.SquareMagnitude() + F*D2F
- 3*(F*DF)*(F*DF)/(Norma*Norma))/(Norma*Norma*Norma));
return Result;
}
//=======================================================================
//function : NormalD0
//purpose : computes Normal to Surface
//=======================================================================
static void NormalD0(const Standard_Real U, const Standard_Real V, const Handle(Adaptor3d_HSurface)& Surf, gp_Dir& Normal, Standard_Integer& OrderU, Standard_Integer& OrderV)
{
// gp_Vec D1U,D1V,D2U,D2V,DUV;
gp_Vec D1U,D1V;
GeomAbs_Shape Cont = (Surf->Surface().UContinuity() < Surf->Surface().VContinuity()) ?
(Surf->Surface().UContinuity()) : (Surf->Surface().VContinuity());
OrderU = OrderV = 0;
#ifdef CHECK
if (Cont == GeomAbs_C0) Geom_UndefinedValue::Raise();
#endif
gp_Pnt P;
Surf->D1(U, V, P, D1U, D1V);
Standard_Real MagTol=0.000000001;
CSLib_NormalStatus NStatus;
CSLib::Normal(D1U, D1V, MagTol, NStatus, Normal);
if (NStatus != CSLib_Defined) {
if (Cont==GeomAbs_C0 ||
Cont==GeomAbs_C1) {
Geom_UndefinedValue::Raise();
}
Standard_Integer MaxOrder=3;
TColgp_Array2OfVec DerNUV(0,MaxOrder,0,MaxOrder);
TColgp_Array2OfVec DerSurf(0,MaxOrder+1,0,MaxOrder+1);
Standard_Integer i,j;//OrderU,OrderV;
Standard_Real Umin,Umax,Vmin,Vmax;
Umin = Surf->Surface().FirstUParameter();
Umax = Surf->Surface().LastUParameter();
Vmin = Surf->Surface().FirstVParameter();
Vmax = Surf->Surface().LastVParameter();
for(i=1;i<=MaxOrder+1;i++){
DerSurf.SetValue(i,0,Surf->DN(U,V,i,0));
}
for(i=0;i<=MaxOrder+1;i++)
for(j=1;j<=MaxOrder+1;j++){
DerSurf.SetValue(i,j,Surf->DN(U,V,i,j));
}
for(i=0;i<=MaxOrder;i++)
for(j=0;j<=MaxOrder;j++){
DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf));
}
CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,
NStatus,Normal,OrderU,OrderV);
if (NStatus != CSLib_Defined) {
#if DEB
cout << U << ", " << V<< endl;
for(i=0;i<=MaxOrder;i++)
for(j=0;j<=MaxOrder;j++){
cout <<"("<<i <<"," << j << ") = "<< DerSurf(i,j).X() <<","
<< DerSurf(i,j).Y() <<"," << DerSurf(i,j).Z() << endl;
}
#endif
Geom_UndefinedValue::Raise();
}
}
}
//=======================================================================
//function : NormalD1
//purpose : computes Normal to Surface and its first derivative
//=======================================================================
void NormalD1 (const Standard_Real U, const Standard_Real V,
const Handle(Adaptor3d_HSurface)& Surf, gp_Dir& Normal,
gp_Vec& D1UNormal, gp_Vec& D1VNormal)
{
#ifdef CHECK
GeomAbs_Shape Cont = (Surf->Surface().UContinuity() < Surf->Surface().VContinuity()) ?
(Surf->Surface().UContinuity()) : (Surf->Surface().VContinuity());
if (Cont==GeomAbs_C0 ||
Cont==GeomAbs_C1) {
Geom_UndefinedDerivative::Raise();
}
#endif
gp_Vec d2u, d2v, d2uv;
gp_Pnt P;
Surf->D2(U, V, P, D1UNormal, D1VNormal, d2u, d2v, d2uv);
Standard_Real MagTol=0.000000001;
CSLib_NormalStatus NStatus;
CSLib::Normal (D1UNormal, D1VNormal, MagTol, NStatus, Normal);
Standard_Integer MaxOrder;
if (NStatus == CSLib_Defined)
MaxOrder=0;
else
MaxOrder=3;
Standard_Integer OrderU,OrderV;
TColgp_Array2OfVec DerNUV(0,MaxOrder+1,0,MaxOrder+1);
TColgp_Array2OfVec DerSurf(0,MaxOrder+2,0,MaxOrder+2);
Standard_Integer i,j;
Standard_Real Umin,Umax,Vmin,Vmax;
Umin = Surf->Surface().FirstUParameter();
Umax = Surf->Surface().LastUParameter();
Vmin = Surf->Surface().FirstVParameter();
Vmax = Surf->Surface().LastVParameter();
DerSurf.SetValue(1, 0, D1UNormal);
DerSurf.SetValue(0, 1, D1VNormal);
DerSurf.SetValue(1, 1, d2uv);
DerSurf.SetValue(2, 0, d2u);
DerSurf.SetValue(0, 2, d2v);
for(i=0;i<=MaxOrder+1;i++)
for(j=i; j<=MaxOrder+2; j++ )
if (i+j > 2) {
DerSurf.SetValue(i,j,Surf->DN(U,V,i,j));
if (i!=j) DerSurf.SetValue(j,i,Surf->DN(U,V,j,i));
}
for(i=0;i<=MaxOrder+1;i++)
for(j=0;j<=MaxOrder+1;j++){
DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf));
}
CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,
NStatus,Normal,OrderU,OrderV);
if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise();
D1UNormal = CSLib::DNNormal(1,0,DerNUV,OrderU,OrderV);
D1VNormal = CSLib::DNNormal(0,1,DerNUV,OrderU,OrderV);
}
//=======================================================================
//function : NormalD2
//purpose : computes Normal to Surface and its first and second derivatives
//=======================================================================
void NormalD2 (const Standard_Real U, const Standard_Real V,
const Handle(Adaptor3d_HSurface)& Surf, gp_Dir& Normal,
gp_Vec& D1UNormal, gp_Vec& D1VNormal,
gp_Vec& D2UNormal, gp_Vec& D2VNormal, gp_Vec& D2UVNormal)
{
#ifdef CHECK
GeomAbs_Shape Cont = (Surf->Surface().UContinuity() < Surf->Surface().VContinuity()) ?
(Surf->Surface().UContinuity()) : (Surf->Surface().VContinuity());
if (Cont == GeomAbs_C0 || Continuity == GeomAbs_C1 ||
Cont == GeomAbs_C2) { Geom_UndefinedDerivative::Raise(); }
#endif
gp_Vec d3u, d3uuv, d3uvv, d3v;
gp_Pnt P;
Surf->D3(U, V, P, D1UNormal, D1VNormal,
D2UNormal, D2VNormal, D2UVNormal,
d3u,d3v, d3uuv, d3uvv);
Standard_Real MagTol=0.000000001;
CSLib_NormalStatus NStatus;
CSLib::Normal (D1UNormal, D1VNormal, MagTol, NStatus, Normal);
Standard_Integer MaxOrder;
if (NStatus == CSLib_Defined)
MaxOrder=0;
else
MaxOrder=3;
Standard_Integer OrderU,OrderV;
TColgp_Array2OfVec DerNUV(0,MaxOrder+2,0,MaxOrder+2);
TColgp_Array2OfVec DerSurf(0,MaxOrder+3,0,MaxOrder+3);
Standard_Integer i,j;
Standard_Real Umin,Umax,Vmin,Vmax;
Umin = Surf->Surface().FirstUParameter();
Umax = Surf->Surface().LastUParameter();
Vmin = Surf->Surface().FirstVParameter();
Vmax = Surf->Surface().LastVParameter();
DerSurf.SetValue(1, 0, D1UNormal);
DerSurf.SetValue(0, 1, D1VNormal);
DerSurf.SetValue(1, 1, D2UVNormal);
DerSurf.SetValue(2, 0, D2UNormal);
DerSurf.SetValue(0, 2, D2VNormal);
DerSurf.SetValue(3, 0, d3u);
DerSurf.SetValue(2, 1, d3uuv);
DerSurf.SetValue(1, 2, d3uvv);
DerSurf.SetValue(0, 3, d3v);
for(i=0;i<=MaxOrder+2;i++)
for(j=i; j<=MaxOrder+3; j++ )
if (i+j > 3) {
DerSurf.SetValue(i,j,Surf->DN(U,V,i,j));
if (i!=j) DerSurf.SetValue(j,i,Surf->DN(U,V,j,i));
}
for(i=0;i<=MaxOrder+2;i++)
for(j=0;j<=MaxOrder+2;j++){
DerNUV.SetValue(i,j,CSLib::DNNUV(i,j,DerSurf));
}
CSLib::Normal(MaxOrder,DerNUV,MagTol,U,V,Umin,Umax,Vmin,Vmax,
NStatus,Normal,OrderU,OrderV);
if (NStatus != CSLib_Defined) Geom_UndefinedValue::Raise();
D1UNormal = CSLib::DNNormal(1,0,DerNUV,OrderU,OrderV);
D1VNormal = CSLib::DNNormal(0,1,DerNUV,OrderU,OrderV);
D2UNormal = CSLib::DNNormal(2,0,DerNUV,OrderU,OrderV);
D2VNormal = CSLib::DNNormal(0,2,DerNUV,OrderU,OrderV);
D2UVNormal = CSLib::DNNormal(1,1,DerNUV,OrderU,OrderV);
}
GeomFill_Darboux::GeomFill_Darboux()
{
}
Handle(GeomFill_TrihedronLaw) GeomFill_Darboux::Copy() const
{
Handle(GeomFill_Darboux) copy = new (GeomFill_Darboux)();
if (!myCurve.IsNull()) copy->SetCurve(myCurve);
return copy;
}
Standard_Boolean GeomFill_Darboux::D0(const Standard_Real Param,gp_Vec& Tangent,gp_Vec& Normal,gp_Vec& BiNormal)
{
gp_Pnt2d C2d;
gp_Vec2d D2d;
gp_Pnt S;
gp_Vec dS_du, dS_dv;
Handle(Adaptor2d_HCurve2d) myCurve2d = Adaptor3d_CurveOnSurfacePtr(&(myTrimmed->Curve()))->GetCurve();
Handle(Adaptor3d_HSurface) mySupport = Adaptor3d_CurveOnSurfacePtr(&(myTrimmed->Curve()))->GetSurface();
Standard_Integer OrderU, OrderV;
myCurve2d->D1(Param, C2d, D2d);
// Normal = dS_du.Crossed(dS_dv).Normalized();
gp_Dir NormalDir;
NormalD0(C2d.X(), C2d.Y(), mySupport, NormalDir, OrderU, OrderV);
BiNormal.SetXYZ(NormalDir.XYZ());
mySupport->D1(C2d.X(), C2d.Y(), S, dS_du, dS_dv);
// if(D2d.Magnitude() <= Precision::Confusion())
// DoTSingular(Param, Order);
Tangent = D2d.X()*dS_du + D2d.Y()*dS_dv;
Tangent.Normalize();
Normal = BiNormal;
Normal ^= Tangent;
return Standard_True;
}
Standard_Boolean GeomFill_Darboux::D1(const Standard_Real Param,
gp_Vec& Tangent,gp_Vec& DTangent,
gp_Vec& Normal,gp_Vec& DNormal,
gp_Vec& BiNormal,gp_Vec& DBiNormal)
{
gp_Pnt2d C2d;
gp_Vec2d D2d, D2_2d;
gp_Pnt S;
gp_Vec dS_du, dS_dv, d2S_du, d2S_dv, d2S_duv, F, DF;
Handle(Adaptor2d_HCurve2d) myCurve2d = Adaptor3d_CurveOnSurfacePtr(&(myTrimmed->Curve()))->GetCurve();
Handle(Adaptor3d_HSurface) mySupport = Adaptor3d_CurveOnSurfacePtr(&(myTrimmed->Curve()))->GetSurface();
// Standard_Integer Order;
myCurve2d->D2(Param, C2d, D2d, D2_2d);
mySupport->D2(C2d.X(), C2d.Y(), S, dS_du, dS_dv,
d2S_du, d2S_dv, d2S_duv);
// if(D2d.Magnitude() <= Precision::Confusion())
// DoTSingular(Param, Order);
F = D2d.X()*dS_du + D2d.Y()*dS_dv;
Tangent = F.Normalized();
DF = D2_2d.X()*dS_du + D2_2d.Y()*dS_dv +
d2S_du*D2d.X()*D2d.X() + 2*d2S_duv*D2d.X()*D2d.Y() +
d2S_dv*D2d.Y()*D2d.Y();
DTangent = FDeriv(F, DF);
gp_Dir NormalDir;
gp_Vec D1UNormal, D1VNormal;
NormalD1(C2d.X(), C2d.Y(), mySupport, NormalDir, D1UNormal, D1VNormal);
BiNormal.SetXYZ(NormalDir.XYZ());
DBiNormal = D1UNormal*D2d.X() + D1VNormal*D2d.Y();
Normal = BiNormal;
Normal ^= Tangent;
DNormal = BiNormal.Crossed(DTangent) + DBiNormal.Crossed(Tangent);
return Standard_True;
}
Standard_Boolean GeomFill_Darboux::D2(const Standard_Real Param,
gp_Vec& Tangent,gp_Vec& DTangent,gp_Vec& D2Tangent,
gp_Vec& Normal,gp_Vec& DNormal,gp_Vec& D2Normal,
gp_Vec& BiNormal,gp_Vec& DBiNormal,gp_Vec& D2BiNormal)
{
gp_Pnt2d C2d;
gp_Vec2d D2d, D2_2d, D3_2d;
gp_Pnt S;
gp_Vec dS_du, dS_dv, d2S_du, d2S_dv, d2S_duv,
d3S_du, d3S_dv, d3S_duuv, d3S_duvv, F, DF, D2F;
Handle(Adaptor2d_HCurve2d) myCurve2d = Adaptor3d_CurveOnSurfacePtr(&(myTrimmed->Curve()))->GetCurve();
Handle(Adaptor3d_HSurface) mySupport = Adaptor3d_CurveOnSurfacePtr(&(myTrimmed->Curve()))->GetSurface();
// Standard_Integer Order;
myCurve2d->D3(Param, C2d, D2d, D2_2d, D3_2d);
mySupport->D3(C2d.X(), C2d.Y(), S, dS_du, dS_dv,
d2S_du, d2S_dv, d2S_duv, d3S_du, d3S_dv, d3S_duuv, d3S_duvv);
// if(D2d.Magnitude() <= Precision::Confusion())
// DoTSingular(Param, Order);
F = D2d.X()*dS_du + D2d.Y()*dS_dv;
Tangent = F.Normalized();
DF = D2_2d.X()*dS_du + D2_2d.Y()*dS_dv +
d2S_du*D2d.X()*D2d.X() + 2*d2S_duv*D2d.X()*D2d.Y() +
d2S_dv*D2d.Y()*D2d.Y();
D2F = D3_2d.X()*dS_du + D3_2d.Y()*dS_dv +
D2_2d.X()*(D2d.X()*d2S_du + D2d.Y()*d2S_duv) +
D2_2d.Y()*(D2d.X()*d2S_duv + D2d.Y()*d2S_dv) +
D2d.X()*D2d.X()*(D2d.X()*d3S_du + D2d.Y()*d3S_duuv) +
D2d.Y()*D2d.Y()*(D2d.X()*d3S_duvv + D2d.Y()*d3S_dv) +
2*(
D2d.X()*D2_2d.X()*d2S_du + D2d.Y()*D2_2d.Y()*d2S_dv +
D2d.X()*D2d.Y()*(D2d.X()*d3S_duuv + D2d.Y()*d3S_duvv) +
d2S_duv*(D2_2d.X()*D2d.Y() + D2d.X()*D2_2d.Y())
);
DTangent = FDeriv(F, DF);
D2Tangent = DDeriv(F, DF, D2F);
gp_Dir NormalDir;
gp_Vec D1UNormal, D1VNormal, D2UNormal, D2VNormal, D2UVNormal;
NormalD2(C2d.X(), C2d.Y(), mySupport, NormalDir, D1UNormal, D1VNormal,
D2UNormal, D2VNormal, D2UVNormal);
BiNormal.SetXYZ(NormalDir.XYZ());
DBiNormal = D1UNormal*D2d.X() + D1VNormal*D2d.Y();
D2BiNormal = D1UNormal*D2_2d.X() + D1VNormal*D2_2d.Y() + D2UNormal*D2d.X()*D2d.X() +
2*D2UVNormal*D2d.X()*D2d.Y() + D2VNormal*D2d.Y()*D2d.Y();
Normal = BiNormal;
Normal ^= Tangent;
DNormal = BiNormal.Crossed(DTangent) + DBiNormal.Crossed(Tangent);
D2Normal = BiNormal.Crossed(D2Tangent) + 2*DBiNormal.Crossed(DTangent) + D2BiNormal.Crossed(Tangent);
return Standard_True;
}
Standard_Integer GeomFill_Darboux::NbIntervals(const GeomAbs_Shape S) const
{
return myCurve->NbIntervals(S);
}
void GeomFill_Darboux::Intervals(TColStd_Array1OfReal& T,const GeomAbs_Shape S) const
{
myCurve->Intervals(T, S);
}
void GeomFill_Darboux::GetAverageLaw(gp_Vec& ATangent,gp_Vec& ANormal,gp_Vec& ABiNormal)
{
Standard_Integer Num = 20; //order of digitalization
gp_Vec T, N, BN;
ATangent = gp_Vec(0, 0, 0);
ANormal = gp_Vec(0, 0, 0);
ABiNormal = gp_Vec(0, 0, 0);
Standard_Real Step = (myTrimmed->LastParameter() -
myTrimmed->FirstParameter()) / Num;
Standard_Real Param;
for (Standard_Integer i = 0; i <= Num; i++) {
Param = myTrimmed->FirstParameter() + i*Step;
if (Param > myTrimmed->LastParameter()) Param = myTrimmed->LastParameter();
D0(Param, T, N, BN);
ATangent += T;
ANormal += N;
ABiNormal += BN;
}
ATangent /= Num + 1;
ANormal /= Num + 1;
ATangent.Normalize();
ABiNormal = ATangent.Crossed(ANormal).Normalized();
ANormal = ABiNormal.Crossed(ATangent);
}
Standard_Boolean GeomFill_Darboux::IsConstant() const
{
return (myCurve->GetType() == GeomAbs_Line);
}
Standard_Boolean GeomFill_Darboux::IsOnlyBy3dCurve() const
{
return Standard_False;
}

View File

@@ -0,0 +1,48 @@
-- File: GeomFill_DegeneratedBound.cdl
-- Created: Tue Dec 5 17:35:39 1995
-- Author: Laurent BOURESCHE
-- <lbo@phylox>
---Copyright: Matra Datavision 1995
class DegeneratedBound from GeomFill inherits Boundary from GeomFill
---Purpose: Description of a degenerated boundary (a point).
uses
Pnt from gp,
Vec from gp
is
Create(Point : Pnt from gp;
First, Last : Real from Standard;
Tol3d : Real from Standard;
Tolang : Real from Standard)
returns mutable DegeneratedBound from GeomFill;
Value(me;
U : Real from Standard)
returns Pnt from gp;
D1(me;
U : Real from Standard;
P : out Pnt from gp;
V : out Vec from gp) ;
Reparametrize(me : mutable;
First, Last : Real from Standard;
HasDF, HasDL : Boolean from Standard;
DF, DL : Real from Standard;
Rev : Boolean from Standard);
Bounds(me; First, Last : out Real from Standard);
IsDegenerated(me) returns Boolean from Standard;
fields
myPoint : Pnt from gp;
myFirst : Real from Standard;
myLast : Real from Standard;
end DegeneratedBound;

View File

@@ -0,0 +1,92 @@
// File: GeomFill_DegeneratedBound.cxx
// Created: Tue Dec 5 17:52:55 1995
// Author: Laurent BOURESCHE
// <lbo@phylox>
#include <GeomFill_DegeneratedBound.ixx>
//=======================================================================
//function : GeomFill_DegeneratedBound
//purpose :
//=======================================================================
GeomFill_DegeneratedBound::GeomFill_DegeneratedBound
(const gp_Pnt& Point,
const Standard_Real First,
const Standard_Real Last,
const Standard_Real Tol3d,
const Standard_Real Tolang) :
GeomFill_Boundary(Tol3d,Tolang),
myPoint(Point),myFirst(First),myLast(Last)
{
}
//=======================================================================
//function : Value
//purpose :
//=======================================================================
//gp_Pnt GeomFill_DegeneratedBound::Value(const Standard_Real U) const
gp_Pnt GeomFill_DegeneratedBound::Value(const Standard_Real ) const
{
return myPoint;
}
//=======================================================================
//function : D1
//purpose :
//=======================================================================
//void GeomFill_DegeneratedBound::D1(const Standard_Real U,
void GeomFill_DegeneratedBound::D1(const Standard_Real ,
gp_Pnt& P,
gp_Vec& V) const
{
P = myPoint;
V.SetCoord(0.,0.,0.);
}
//=======================================================================
//function : Reparametrize
//purpose :
//=======================================================================
void GeomFill_DegeneratedBound::Reparametrize(const Standard_Real First,
const Standard_Real Last,
const Standard_Boolean ,
const Standard_Boolean ,
const Standard_Real ,
const Standard_Real ,
const Standard_Boolean )
{
myFirst = First;
myLast = Last;
}
//=======================================================================
//function : Bounds
//purpose :
//=======================================================================
void GeomFill_DegeneratedBound::Bounds(Standard_Real& First,
Standard_Real& Last) const
{
First = myFirst;
Last = myLast;
}
//=======================================================================
//function : IsDegenerated
//purpose :
//=======================================================================
Standard_Boolean GeomFill_DegeneratedBound::IsDegenerated() const
{
return Standard_True;
}

View File

@@ -0,0 +1,120 @@
-- File: GeomFill_DraftTrihedron.cdl
-- Created: Tue Apr 14 09:48:24 1998
-- Author: Stephanie HUMEAU
-- <shu@sun17>
---Copyright: Matra Datavision 1998
----------------------------------------------------
-- Triedre de Frenet pour une surface de depouille
----------------------------------------------------
class DraftTrihedron from GeomFill
inherits TrihedronLaw from GeomFill
uses
Shape from GeomAbs,
Array1OfReal from TColStd,
Vec from gp
raises
OutOfRange, ConstructionError
is
Create (BiNormal : Vec from gp;
Angle : Real )
returns DraftTrihedron from GeomFill;
SetAngle(me : mutable; Angle : Real)
is static;
Copy(me) returns TrihedronLaw from GeomFill
is redefined;
D0( me : mutable;
Param : Real;
Tangent : out Vec from gp;
Normal : out Vec from gp;
BiNormal : out Vec from gp)
returns Boolean is redefined;
---Purpose: compute Triedrhon and derivative Trihedron on curve at
-- parameter <Param>
-- Warning : It used only for C1 or C2 aproximation
D1( me : mutable;
Param: Real;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp)
returns Boolean is redefined;
---Purpose: compute Trihedron on curve
-- first and seconde derivatives.
-- Warning : It used only for C2 aproximation
D2( me : mutable;
Param: Real;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
D2Tangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
D2Normal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp;
D2BiNormal : out Vec from gp)
returns Boolean is redefined;
--
-- =================== Management of continuity ===================
--
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>.
-- May be one if Continuity(me) >= <S>
returns Integer is redefined;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is redefined;
-- ===================== To help computation of Tolerance ============
GetAverageLaw(me : mutable;
ATangent : out Vec from gp;
ANormal : out Vec from gp;
ABiNormal : out Vec from gp)
---Purpose: Get average value of Tangent(t) and Normal(t) it is usefull to
-- make fast approximation of rational surfaces.
is redefined;
-- =================== To help Particular case ===============
IsConstant(me)
---Purpose: Say if the law is Constant.
returns Boolean
is redefined;
IsOnlyBy3dCurve(me)
---Purpose: Return True.
returns Boolean
is redefined;
fields
B : Vec from gp;
myAngle : Real from Standard;
myCos : Real;
end DraftTrihedron;

View File

@@ -0,0 +1,370 @@
// File: GeomFill_DraftTrihedron.cxx
// Created: Wed Apr 15 14:59:31 1998
// Author: Stephanie HUMEAU
// <shu@sun17>
#include <GeomFill_DraftTrihedron.ixx>
#include <Precision.hxx>
#include <GeomAbs_CurveType.hxx>
#include <Adaptor3d_HCurve.hxx>
//=======================================================================
//function : DDeriv
//purpose : computes (F/|F|)''
//=======================================================================
static gp_Vec DDeriv(const gp_Vec& F, const gp_Vec& DF, const gp_Vec& D2F)
{
Standard_Real Norma = F.Magnitude();
#ifdef DEB
Standard_Real dot = F.Dot(DF);
#else
F.Dot(DF);
#endif
gp_Vec Result = (D2F - 2*DF*(F*DF)/(Norma*Norma))/Norma -
F*((DF.SquareMagnitude() + F*D2F
- 3*(F*DF)*(F*DF)/(Norma*Norma))/(Norma*Norma*Norma));
return Result;
}
//=======================================================================
//function : DraftTrihedron
//purpose : Constructor
//=======================================================================
GeomFill_DraftTrihedron::GeomFill_DraftTrihedron(const gp_Vec& BiNormal,
const Standard_Real Angle)
{
B = BiNormal;
B.Normalize();
SetAngle(Angle);
}
//=======================================================================
//function : Setangle
//purpose :
//=======================================================================
void GeomFill_DraftTrihedron::SetAngle(const Standard_Real Angle)
{
myAngle = PI/2 + Angle;
myCos = Cos(myAngle);
}
//=======================================================================
//function : D0
//purpose : calculation of trihedron
//=======================================================================
Standard_Boolean GeomFill_DraftTrihedron::D0(const Standard_Real Param,
gp_Vec& Tangent,
gp_Vec& Normal,
gp_Vec& BiNormal)
{
gp_Pnt P;
gp_Vec T;
myTrimmed->D1(Param,P,T);
T.Normalize();
gp_Vec b = T.Crossed(B);
Standard_Real normb = b.Magnitude();
b /= normb;
if (normb < 1.e-12)
return Standard_False;
gp_Vec v = b.Crossed(T);
Standard_Real mu = myCos ;
mu = myCos;
//La Normal est portee par la regle
Normal.SetLinearForm(Sqrt(1-mu*mu), b, mu, v);
// Le reste suit....
// La tangente est perpendiculaire a la normale et a la direction de depouille
Tangent = Normal.Crossed(B);
Tangent.Normalize();
BiNormal = Tangent;
BiNormal.Cross(Normal);
return Standard_True;
}
//=======================================================================
//function : D1
//purpose : calculation of trihedron and first derivative
//=======================================================================
Standard_Boolean GeomFill_DraftTrihedron::D1(const Standard_Real Param,
gp_Vec& Tangent,
gp_Vec& DTangent,
gp_Vec& Normal,
gp_Vec& DNormal,
gp_Vec& BiNormal,
gp_Vec& DBiNormal)
{
gp_Pnt P;
gp_Vec T, DT, aux;
myTrimmed->D2(Param, P, T, aux);
Standard_Real normT, normb;
normT = T.Magnitude();
T /= normT;
DT.SetLinearForm(-(T.Dot(aux)), T, aux);
DT /= normT;
gp_Vec db, b = T.Crossed(B);
normb = b.Magnitude();
if (normb < 1.e-12)
return Standard_False;
b /= normb;
aux = DT.Crossed(B);
db.SetLinearForm( -(b.Dot(aux)), b, aux);
db /= normb;
gp_Vec v = b.Crossed(T);
gp_Vec dv = db.Crossed(T) + b.Crossed(DT);
Standard_Real mu = myCos;
Normal.SetLinearForm(Sqrt(1-mu*mu), b, mu, v);
DNormal.SetLinearForm(Sqrt(1-mu*mu), db, mu, dv);
Tangent = Normal.Crossed(B);
normT = Tangent.Magnitude();
Tangent/= normT;
aux = DNormal.Crossed(B);
DTangent.SetLinearForm( -(Tangent.Dot(aux)), Tangent, aux);
DTangent /= normT;
BiNormal = Tangent;
BiNormal.Cross(Normal);
DBiNormal.SetLinearForm(DTangent.Crossed(Normal),Tangent.Crossed(DNormal));
return Standard_True;
}
//=======================================================================
//function : D2
//purpose : calculation of trihedron and derivatives 1 et 2
//=======================================================================
Standard_Boolean GeomFill_DraftTrihedron::D2(const Standard_Real Param,
gp_Vec& Tangent,
gp_Vec& DTangent,
gp_Vec& D2Tangent,
gp_Vec& Normal,
gp_Vec& DNormal,
gp_Vec& D2Normal,
gp_Vec& BiNormal,
gp_Vec& DBiNormal,
gp_Vec& D2BiNormal)
{
gp_Pnt P;
gp_Vec T, DT, D2T, aux, aux2;
Standard_Real dot;
myTrimmed->D3(Param, P, T, aux, aux2);
Standard_Real normT, normb;
D2T = DDeriv(T, aux, aux2);
normT = T.Magnitude();
T /= normT;
dot = T.Dot(aux);
DT.SetLinearForm(-dot, T, aux);
DT /= normT;
gp_Vec db, d2b, b = T.Crossed(B);
normb = b.Magnitude();
if (normb < 1.e-12)
return Standard_False;
aux = DT.Crossed(B); aux2 = D2T.Crossed(B);
d2b = DDeriv(b, aux, aux2);
b /= normb;
dot = b.Dot(aux);
db.SetLinearForm( -dot, b, aux);
db /= normb;
gp_Vec v = b.Crossed(T);
gp_Vec dv = db.Crossed(T) + b.Crossed(DT);
gp_Vec d2v = d2b.Crossed(T) + 2*db.Crossed(DT) + b.Crossed(D2T);
Standard_Real mu = myCos, rac;
rac = Sqrt(1-mu*mu);
Normal .SetLinearForm( rac, b , mu, v);
DNormal .SetLinearForm( rac, db , mu, dv);
D2Normal.SetLinearForm( rac, d2b, mu, d2v);
Tangent = Normal.Crossed(B);
normT = Tangent.Magnitude();
aux = DNormal.Crossed(B);
aux2 = D2Normal.Crossed(B);
D2Tangent = DDeriv(Tangent, aux, aux2);
Tangent/= normT;
dot = Tangent.Dot(aux);
DTangent.SetLinearForm( -dot, Tangent, aux);
DTangent /= normT;
BiNormal = Tangent;
BiNormal.Cross(Normal);
DBiNormal.SetLinearForm(DTangent.Crossed(Normal),Tangent.Crossed(DNormal));
D2BiNormal.SetLinearForm(1, D2Tangent.Crossed(Normal),
2, DTangent.Crossed(DNormal),
Tangent.Crossed(D2Normal));
return Standard_True;
}
//=======================================================================
//function : Copy
//purpose :
//=======================================================================
Handle(GeomFill_TrihedronLaw) GeomFill_DraftTrihedron::Copy() const
{
Handle(GeomFill_DraftTrihedron) copy =
new (GeomFill_DraftTrihedron) (B,myAngle-PI/2);
copy->SetCurve(myCurve);
return copy;
}
//=======================================================================
//function : NbIntervals
//purpose :
//=======================================================================
Standard_Integer GeomFill_DraftTrihedron::NbIntervals(const GeomAbs_Shape S) const
{
GeomAbs_Shape tmpS=GeomAbs_C0;
switch (S) {
case GeomAbs_C0: tmpS = GeomAbs_C2; break;
case GeomAbs_C1: tmpS = GeomAbs_C3; break;
case GeomAbs_C2:
case GeomAbs_C3:
case GeomAbs_CN: tmpS = GeomAbs_CN; break;
default: Standard_OutOfRange::Raise();
}
return myCurve->NbIntervals(tmpS);
}
//======================================================================
//function :Intervals
//purpose :
//=======================================================================
void GeomFill_DraftTrihedron::Intervals(TColStd_Array1OfReal& TT,
const GeomAbs_Shape S) const
{
GeomAbs_Shape tmpS=GeomAbs_C0;
switch (S) {
case GeomAbs_C0: tmpS = GeomAbs_C2; break;
case GeomAbs_C1: tmpS = GeomAbs_C3; break;
case GeomAbs_C2:
case GeomAbs_C3:
case GeomAbs_CN: tmpS = GeomAbs_CN; break;
default: Standard_OutOfRange::Raise();
}
myCurve->Intervals(TT, tmpS);
}
//=======================================================================
//function : GetAverageLaw
//purpose :
//=======================================================================
void GeomFill_DraftTrihedron::GetAverageLaw(gp_Vec& ATangent,
gp_Vec& ANormal,
gp_Vec& ABiNormal)
{
Standard_Integer Num = 20; //order of digitalization
gp_Vec T, N, BN;
ATangent = gp_Vec(0, 0, 0);
ANormal = gp_Vec(0, 0, 0);
ABiNormal = gp_Vec(0, 0, 0);
Standard_Real Step = (myTrimmed->LastParameter() -
myTrimmed->FirstParameter()) / Num;
Standard_Real Param;
for (Standard_Integer i = 0; i <= Num; i++) {
Param = myTrimmed->FirstParameter() + i*Step;
if (Param > myTrimmed->LastParameter()) Param = myTrimmed->LastParameter();
D0(Param, T, N, BN);
ATangent += T;
ANormal += N;
ABiNormal += BN;
}
ANormal /= Num + 1;
ABiNormal /= Num + 1;
ATangent /= Num + 1;
}
//=======================================================================
//function : IsConstant
//purpose :
//=======================================================================
Standard_Boolean GeomFill_DraftTrihedron::IsConstant() const
{
return (myCurve->GetType() == GeomAbs_Line);
}
//=======================================================================
//function : IsOnlyBy3dCurve
//purpose :
//=======================================================================
Standard_Boolean GeomFill_DraftTrihedron::IsOnlyBy3dCurve() const
{
GeomAbs_CurveType TheType = myCurve->GetType();
gp_Ax1 TheAxe;
switch (TheType) {
case GeomAbs_Circle:
{
TheAxe = myCurve->Circle().Axis();
break;
}
case GeomAbs_Ellipse:
{
TheAxe = myCurve->Ellipse().Axis();
break;
}
case GeomAbs_Hyperbola:
{
TheAxe = myCurve->Hyperbola().Axis();
break;
}
case GeomAbs_Parabola:
{
TheAxe = myCurve->Parabola().Axis();
break;
}
case GeomAbs_Line:
{ //La normale du plan de la courbe est il perpendiculaire a la BiNormale ?
gp_Vec V;
V.SetXYZ(myCurve->Line().Direction().XYZ());
return V.IsParallel(B, Precision::Angular());
}
default:
return Standard_False; // pas de risques
}
// La normale du plan de la courbe est il // a la BiNormale ?
gp_Vec V;
V.SetXYZ(TheAxe.Direction().XYZ());
return V.IsParallel(B, Precision::Angular());
}

View File

@@ -0,0 +1,203 @@
-- File: GeomFill_EvolvedSection.cdl
-- Created: Mon Aug 17 15:45:13 1998
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1998
class EvolvedSection from GeomFill inherits SectionLaw from GeomFill
---Purpose: Define an Constant Section Law
uses
Curve from Geom,
BSplineSurface from Geom,
BSplineCurve from Geom,
Function from Law,
Shape from GeomAbs,
Pnt from gp,
Array1OfPnt from TColgp,
Array1OfVec from TColgp,
Array1OfInteger from TColStd,
Array1OfReal from TColStd
raises
OutOfRange
is
Create(C : Curve from Geom;
L : Function from Law)
---Purpose: Make an SectionLaw with a Curve and a real Law.
returns EvolvedSection from GeomFill;
--
--========== To compute Sections and derivatives Sections
--
D0(me : mutable;
Param: Real;
Poles : out Array1OfPnt from TColgp;
Weigths : out Array1OfReal from TColStd)
---Purpose: compute the section for v = param
returns Boolean is redefined;
D1(me : mutable;
Param: Real;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
Weigths : out Array1OfReal from TColStd;
DWeigths : out Array1OfReal from TColStd)
---Purpose: compute the first derivative in v direction of the
-- section for v = param
-- Warning : It used only for C1 or C2 aproximation
returns Boolean
is redefined;
D2(me : mutable;
Param: Real;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
D2Poles : out Array1OfVec from TColgp;
Weigths : out Array1OfReal from TColStd;
DWeigths : out Array1OfReal from TColStd;
D2Weigths : out Array1OfReal from TColStd)
---Purpose: compute the second derivative in v direction of the
-- section for v = param
-- Warning : It used only for C2 aproximation
returns Boolean
is redefined;
BSplineSurface(me)
---Purpose: give if possible an bspline Surface, like iso-v are the
-- section. If it is not possible this methode have to
-- get an Null Surface. Is it the default implementation.
returns BSplineSurface from Geom
is redefined;
SectionShape(me; NbPoles : out Integer from Standard;
NbKnots : out Integer from Standard;
Degree : out Integer from Standard)
---Purpose: get the format of an section
is redefined;
Knots(me; TKnots: out Array1OfReal from TColStd)
---Purpose: get the Knots of the section
is redefined;
Mults(me; TMults: out Array1OfInteger from TColStd)
---Purpose: get the Multplicities of the section
is redefined;
IsRational(me)
---Purpose: Returns if the sections are rationnal or not
returns Boolean is redefined;
IsUPeriodic(me)
---Purpose: Returns if the sections are periodic or not
returns Boolean is redefined;
IsVPeriodic(me)
---Purpose: Returns if the law isperiodic or not
returns Boolean is redefined;
--
-- =================== Management of continuity ===================
--
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>.
-- May be one if Continuity(me) >= <S>
returns Integer is redefined;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is redefined;
SetInterval(me: mutable; First, Last: Real from Standard)
---Purpose: Sets the bounds of the parametric interval on
-- the function
-- This determines the derivatives in these values if the
-- function is not Cn.
is redefined;
GetInterval(me; First, Last: out Real from Standard)
---Purpose: Gets the bounds of the parametric interval on
-- the function
is redefined;
GetDomain(me; First, Last: out Real from Standard)
---Purpose: Gets the bounds of the function parametric domain.
-- Warning: This domain it is not modified by the
-- SetValue method
is redefined;
-- ===================== To help computation of Tolerance ======
-- Evaluation of error, in 2d space, or on rational function, is
-- difficult. The following methods can help the approximation to
-- make good evaluation and use good tolerances.
--
-- It is not necessary for the following informations to be very
-- precise. A fast evaluation is sufficient.
GetTolerance(me;
BoundTol, SurfTol, AngleTol : Real;
Tol3d : out Array1OfReal)
---Purpose: Returns the tolerances associated at each poles to
-- reach in approximation, to satisfy: BoundTol error
-- at the Boundary AngleTol tangent error at the
-- Boundary (in radian) SurfTol error inside the
-- surface.
is redefined;
BarycentreOfSurf(me)
---Purpose: Get the barycentre of Surface.
-- An very poor estimation is sufficent.
-- This information is usefull to perform well
-- conditioned rational approximation.
-- Warning: Used only if <me> IsRational
returns Pnt from gp
is redefined;
MaximalSection(me) returns Real
---Purpose: Returns the length of the greater section. This
-- information is usefull to G1's control.
-- Warning: With an little value, approximation can be slower.
is redefined;
GetMinimalWeight(me; Weigths : out Array1OfReal from TColStd)
---Purpose: Compute the minimal value of weight for each poles
-- in all sections.
-- This information is usefull to control error
-- in rational approximation.
-- Warning: Used only if <me> IsRational
is redefined;
IsConstant(me; Error : out Real)
---Purpose: return True If the Law isConstant
returns Boolean
is redefined;
ConstantSection(me)
---Purpose: Return the constant Section if <me> IsConstant.
--
returns Curve from Geom
is redefined;
fields
First, Last : Real;
mySection : Curve from Geom;
myLaw : Function from Law;
TLaw : Function from Law;
myCurve : BSplineCurve from Geom;
end EvolvedSection;

View File

@@ -0,0 +1,355 @@
// File: GeomFill_EvolvedSection.cxx
// Created: Mon Aug 17 15:51:00 1998
// Author: Philippe MANGIN
// <pmn@sgi29>
#include <stdio.h>
#include <GeomFill_EvolvedSection.ixx>
#include <GeomConvert.hxx>
#include <Convert_ParameterisationType.hxx>
#include <Geom_Geometry.hxx>
#include <Geom_Surface.hxx>
#include <Geom_BSplineSurface.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <TColgp_Array2OfPnt.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <Precision.hxx>
#ifdef DRAW
#include <DrawTrSurf.hxx>
static Standard_Integer NumSec = 0;
static Standard_Boolean Affich = 0;
#endif
GeomFill_EvolvedSection::GeomFill_EvolvedSection(const Handle(Geom_Curve)& C,
const Handle(Law_Function)& L)
{
Standard_Boolean Bof;
L->Bounds(First, Last);
mySection = Handle(Geom_Curve)::DownCast(C->Copy());
myLaw = L->Trim(First, Last, 1.e-20);
TLaw = myLaw;
myCurve = Handle(Geom_BSplineCurve)::DownCast(C);
if (myCurve.IsNull()) {
myCurve = GeomConvert::CurveToBSplineCurve(C, Convert_QuasiAngular);
if (myCurve->IsPeriodic()) {
Standard_Integer M = myCurve->Degree()/2+1;
Bof = myCurve->RemoveKnot(1, M, Precision::Confusion());
}
}
#if DRAW
if (Affich) {
char* name = new char[100];
sprintf(name,"UnifSect_%d",++NumSec);
DrawTrSurf::Set(name, myCurve);
delete name;
}
#endif
}
//=======================================================
// Purpose :D0
//=======================================================
Standard_Boolean GeomFill_EvolvedSection::D0(const Standard_Real U,
TColgp_Array1OfPnt& Poles,
TColStd_Array1OfReal& Weights)
{
Standard_Real val;
Standard_Integer ii, L = Poles.Length();
val= TLaw->Value(U);
myCurve->Poles(Poles);
for (ii=1; ii<=L; ii++) {
Poles(ii).ChangeCoord() *= val;
}
myCurve->Weights(Weights);
return Standard_True;
}
//=======================================================
// Purpose :D1
//=======================================================
Standard_Boolean GeomFill_EvolvedSection::D1(const Standard_Real U,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfVec& DPoles,
TColStd_Array1OfReal& Weights,
TColStd_Array1OfReal& DWeights)
{
Standard_Real val, dval;
Standard_Integer ii, L = Poles.Length();
TLaw->D1(U, val, dval);
myCurve->Poles(Poles);
myCurve->Weights(Weights);
for (ii=1; ii<=L; ii++) {
DPoles(ii).SetXYZ(Poles(ii).XYZ());
DPoles(ii) *= dval;
Poles(ii).ChangeCoord() *= val;
}
DWeights.Init(0);
return Standard_True;
}
//=======================================================
// Purpose :D2
//=======================================================
Standard_Boolean GeomFill_EvolvedSection::D2(const Standard_Real U,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfVec& DPoles,
TColgp_Array1OfVec& D2Poles,
TColStd_Array1OfReal& Weights,
TColStd_Array1OfReal& DWeights,
TColStd_Array1OfReal& D2Weights)
{
Standard_Real val, dval, d2val;
Standard_Integer ii, L = Poles.Length();
TLaw->D2(U, val, dval, d2val);
myCurve->Poles(Poles);
myCurve->Weights(Weights);
for (ii=1; ii<=L; ii++) {
DPoles(ii).SetXYZ(Poles(ii).XYZ());
D2Poles(ii) = DPoles(ii);
D2Poles(ii) *= d2val;
DPoles(ii) *= dval;
Poles(ii).ChangeCoord() *= val;
}
DWeights.Init(0);
D2Weights.Init(0);
return Standard_True;
}
//=======================================================
// Purpose :BSplineSurface()
//=======================================================
Handle(Geom_BSplineSurface) GeomFill_EvolvedSection::BSplineSurface() const
{
/* Standard_Integer ii, NbPoles = myCurve->NbPoles();
TColgp_Array2OfPnt Poles( 1, NbPoles, 1, 2);
TColStd_Array1OfReal UKnots(1,myCurve->NbKnots()), VKnots(1,2);
TColStd_Array1OfInteger UMults(1,myCurve->NbKnots()), VMults(1,2);
for (ii=1; ii <= NbPoles; ii++) {
Poles(ii, 1) = Poles(ii, 2) = myCurve->Pole(ii);
}
myCurve->Knots(UKnots);
VKnots(1) = First;
VKnots(2) = Last;
myCurve->Multiplicities(UMults);
VMults.Init(2);
Handle(Geom_BSplineSurface) BS =
new (Geom_BSplineSurface) ( Poles,
UKnots, VKnots,
UMults, VMults,
myCurve->Degree(), 1,
myCurve->IsPeriodic());*/
Handle(Geom_BSplineSurface) BS;
BS.Nullify();
return BS;
}
//=======================================================
// Purpose :SectionShape
//=======================================================
void GeomFill_EvolvedSection::SectionShape(Standard_Integer& NbPoles,
Standard_Integer& NbKnots,
Standard_Integer& Degree) const
{
NbPoles = myCurve->NbPoles();
NbKnots = myCurve->NbKnots();
Degree = myCurve->Degree();
}
void GeomFill_EvolvedSection::Knots(TColStd_Array1OfReal& TKnots) const
{
myCurve->Knots(TKnots);
}
//=======================================================
// Purpose :Mults
//=======================================================
void GeomFill_EvolvedSection::Mults(TColStd_Array1OfInteger& TMults) const
{
myCurve->Multiplicities(TMults);
}
//=======================================================
// Purpose :IsRational
//=======================================================
Standard_Boolean GeomFill_EvolvedSection::IsRational() const
{
return myCurve->IsRational();
}
//=======================================================
// Purpose :IsUPeriodic
//=======================================================
Standard_Boolean GeomFill_EvolvedSection::IsUPeriodic() const
{
return myCurve->IsPeriodic();
}
//=======================================================
// Purpose :IsVPeriodic
//=======================================================
Standard_Boolean GeomFill_EvolvedSection::IsVPeriodic() const
{
return
(Abs(myLaw->Value(First) - myLaw->Value(Last)) < Precision::Confusion());
}
//=======================================================
// Purpose :NbIntervals
//=======================================================
Standard_Integer GeomFill_EvolvedSection::NbIntervals(const GeomAbs_Shape S) const
{
return myLaw->NbIntervals(S) ;
}
//=======================================================
// Purpose :Intervals
//=======================================================
void GeomFill_EvolvedSection::Intervals(TColStd_Array1OfReal& T,
const GeomAbs_Shape S) const
{
myLaw->Intervals(T, S) ;
}
//=======================================================
// Purpose : SetInterval
//=======================================================
void GeomFill_EvolvedSection::SetInterval(const Standard_Real F,
const Standard_Real L)
{
TLaw = myLaw->Trim(F, L, Precision::PConfusion());
}
//=======================================================
// Purpose : GetInterval
//=======================================================
void GeomFill_EvolvedSection::GetInterval(Standard_Real& F,
Standard_Real& L) const
{
TLaw->Bounds(F, L);
}
//=======================================================
// Purpose : GetDomain
//=======================================================
void GeomFill_EvolvedSection::GetDomain(Standard_Real& F,
Standard_Real& L) const
{
F = First;
L = Last;
}
//=======================================================
// Purpose : GetTolerance
//=======================================================
void GeomFill_EvolvedSection::GetTolerance(const Standard_Real BoundTol,
const Standard_Real SurfTol,
// const Standard_Real AngleTol,
const Standard_Real ,
TColStd_Array1OfReal& Tol3d) const
{
Tol3d.Init(SurfTol);
if (BoundTol<SurfTol) {
Tol3d(Tol3d.Lower()) = BoundTol;
Tol3d(Tol3d.Upper()) = BoundTol;
}
}
//=======================================================
// Purpose :
//=======================================================
gp_Pnt GeomFill_EvolvedSection::BarycentreOfSurf() const
{
Standard_Real U = mySection->FirstParameter(), Delta, b;
Standard_Integer ii;
gp_Pnt P, Bary;
Delta = ( myCurve->LastParameter() - U ) / 20;
Bary.SetCoord(0., 0., 0.);
for (ii=0 ; ii <=20; ii++, U+=Delta) {
P = myCurve->Value(U);
Bary.ChangeCoord() += P.XYZ();
}
U = First;
Delta = ( Last - First) / 20;
for (ii=0, b=0.0; ii <=20; ii++, U+=Delta) {
b += myLaw->Value(U);
}
Bary.ChangeCoord() *= b/(21*21);
return Bary;
}
Standard_Real GeomFill_EvolvedSection::MaximalSection() const
{
Standard_Real L, val, max, U, Delta;
Standard_Integer ii;
GeomAdaptor_Curve AC (mySection);
L = GCPnts_AbscissaPoint::Length(AC);
Delta = ( Last - First) / 20;
for (ii=0, max=0.0, U = First; ii <=20; ii++, U+=Delta) {
val = myLaw->Value(U);
if (val>max) max = val;
}
return L*max;
}
void GeomFill_EvolvedSection::GetMinimalWeight(TColStd_Array1OfReal& Weights) const
{
if (myCurve->IsRational()) {
myCurve->Weights(Weights);
}
else {
Weights.Init(1);
}
}
Standard_Boolean GeomFill_EvolvedSection::IsConstant(Standard_Real& Error) const
{
// Standard_Real isconst = Standard_False;
Standard_Boolean isconst = Standard_False;
Error = 0.;
return isconst;
}
Handle(Geom_Curve) GeomFill_EvolvedSection::ConstantSection() const
{
Standard_Real Err, scale;
if (!IsConstant(Err)) StdFail_NotDone::Raise("The Law is not Constant!");
gp_Trsf T;
gp_Pnt P(0, 0, 0);
scale = myLaw->Value(First) +
myLaw->Value((First+Last)/2) +
myLaw->Value(Last);
T.SetScale(P, scale/3);
Handle(Geom_Curve) C;
C = Handle(Geom_Curve)::DownCast( mySection->Copy());
C->Transform(T);
return C;
}

View File

@@ -0,0 +1,49 @@
-- File: GeomFill_Filling.cdl
-- Created: Tue Sep 28 12:37:19 1993
-- Author: Bruno DUMORTIER
-- <dub@sdsun1>
---Copyright: Matra Datavision 1993
class Filling from GeomFill
uses
Array1OfPnt from TColgp,
Array2OfPnt from TColgp,
HArray2OfPnt from TColgp,
Array1OfReal from TColStd,
Array2OfReal from TColStd,
HArray2OfReal from TColStd
raises
NoSuchObject from Standard
is
Create;
NbUPoles(me) returns Integer from Standard
is static;
NbVPoles(me) returns Integer from Standard
is static;
Poles(me; Poles : in out Array2OfPnt from TColgp)
is static;
isRational(me) returns Boolean from Standard
is static;
Weights(me; Weights : in out Array2OfReal from TColStd)
raises
NoSuchObject from Standard
is static;
fields
IsRational : Boolean from Standard is protected;
myPoles : HArray2OfPnt from TColgp is protected;
myWeights : HArray2OfReal from TColStd is protected;
end Filling;

View File

@@ -0,0 +1,71 @@
// File: GeomFill_Filling.cxx
// Created: Tue Sep 28 17:42:54 1993
// Author: Bruno DUMORTIER
// <dub@sdsun1>
#include <GeomFill_Filling.ixx>
#include <gp_Pnt.hxx>
//=======================================================================
//function : GeomFill_Filling
//purpose :
//=======================================================================
GeomFill_Filling::GeomFill_Filling()
{
}
//=======================================================================
//function : NbUPoles
//purpose :
//=======================================================================
Standard_Integer GeomFill_Filling::NbUPoles() const
{
return myPoles->ColLength();
}
//=======================================================================
//function : NbVPoles
//purpose :
//=======================================================================
Standard_Integer GeomFill_Filling::NbVPoles() const
{
return myPoles->RowLength();
}
//=======================================================================
//function : Poles
//purpose :
//=======================================================================
void GeomFill_Filling::Poles(TColgp_Array2OfPnt& Poles)const
{
Poles = myPoles->ChangeArray2();
}
//=======================================================================
//function : isRational
//purpose :
//=======================================================================
Standard_Boolean GeomFill_Filling::isRational()const
{
return IsRational;
}
//=======================================================================
//function : Weights
//purpose :
//=======================================================================
void GeomFill_Filling::Weights(TColStd_Array2OfReal& Weights)const
{
Weights = myWeights->ChangeArray2();
}

111
src/GeomFill/GeomFill_Fixed.cdl Executable file
View File

@@ -0,0 +1,111 @@
-- File: GeomFill_Fixed.cdl
-- Created: Tue Dec 9 18:33:12 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
class Fixed from GeomFill
inherits TrihedronLaw from GeomFill
---Purpose: Defined an constant TrihedronLaw
uses
Shape from GeomAbs,
Array1OfReal from TColStd,
Vec from gp
raises
OutOfRange, ConstructionError
is
Create(Tangent, Normal : Vec from gp)
returns Fixed from GeomFill
raises ConstructionError;
-- if <Tangent> and <Normal> are colinear
Copy(me)
returns TrihedronLaw from GeomFill
is redefined;
--
--
--========== To compute Location and derivatives Location
--
D0(me : mutable;
Param: Real;
Tangent : out Vec from gp;
Normal : out Vec from gp;
BiNormal : out Vec from gp)
---Purpose: compute Triedrhon on curve at parameter <Param>
returns Boolean is redefined;
D1(me : mutable;
Param: Real;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp)
---Purpose: compute Triedrhon and derivative Trihedron on curve
-- at parameter <Param>
-- Warning : It used only for C1 or C2 aproximation
returns Boolean
is redefined;
D2(me : mutable;
Param: Real;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
D2Tangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
D2Normal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp;
D2BiNormal : out Vec from gp)
---Purpose: compute Trihedron on curve
-- first and seconde derivatives.
-- Warning : It used only for C2 aproximation
returns Boolean
is redefined;
--
-- =================== Management of continuity ===================
--
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>.
-- May be one if Continuity(me) >= <S>
returns Integer is redefined;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is redefined;
-- ===================== To help computation of Tolerance ============
GetAverageLaw(me : mutable;
ATangent : out Vec from gp;
ANormal : out Vec from gp;
ABiNormal : out Vec from gp)
---Purpose: Get average value of Tangent(t) and Normal(t) it is usfull to
-- make fast approximation of rational surfaces.
is redefined;
-- =================== To help Particular case ===============
IsConstant(me)
---Purpose: Return True.
returns Boolean
is redefined;
fields
T, N, B : Vec from gp;
end Fixed;

108
src/GeomFill/GeomFill_Fixed.cxx Executable file
View File

@@ -0,0 +1,108 @@
// File: GeomFill_Fixed.cxx
// Created: Wed Dec 10 10:26:36 1997
// Author: Philippe MANGIN
// <pmn@sgi29>
#include <GeomFill_Fixed.ixx>
#include <Precision.hxx>
GeomFill_Fixed::GeomFill_Fixed(const gp_Vec& Tangent,
const gp_Vec& Normal)
{
if (Tangent.IsParallel(Normal, 0.01) )
Standard_ConstructionError::Raise(
"GeomFill_Fixed : Two parallel vectors !");
T = Tangent;
T.Normalize();
N = Normal;
N.Normalize();
B = T ^ N;
B.Normalize();
}
Handle(GeomFill_TrihedronLaw) GeomFill_Fixed::Copy() const
{
Handle(GeomFill_Fixed) copy = new (GeomFill_Fixed)(T, N);
copy->SetCurve(myCurve);
return copy;
}
Standard_Boolean GeomFill_Fixed::D0(const Standard_Real,
gp_Vec& Tangent,
gp_Vec& Normal,
gp_Vec& BiNormal)
{
Tangent = T;
Normal = N;
BiNormal = B;
return Standard_True;
}
Standard_Boolean GeomFill_Fixed::D1(const Standard_Real,
gp_Vec& Tangent,
gp_Vec& DTangent,
gp_Vec& Normal,
gp_Vec& DNormal,
gp_Vec& BiNormal,
gp_Vec& DBiNormal)
{
Tangent = T;
Normal = N;
BiNormal = B;
gp_Vec V0(0,0,0);
DTangent = DNormal = DBiNormal = V0;
return Standard_True;
}
Standard_Boolean GeomFill_Fixed::D2(const Standard_Real,
gp_Vec& Tangent,
gp_Vec& DTangent,
gp_Vec& D2Tangent,
gp_Vec& Normal,
gp_Vec& DNormal,
gp_Vec& D2Normal,
gp_Vec& BiNormal,
gp_Vec& DBiNormal,
gp_Vec& D2BiNormal)
{
Tangent = T;
Normal = N;
BiNormal = B;
gp_Vec V0(0,0,0);
DTangent = D2Tangent = V0;
DNormal = D2Normal = V0;
DBiNormal = D2BiNormal = V0;
return Standard_True;
}
Standard_Integer GeomFill_Fixed::NbIntervals(const GeomAbs_Shape) const
{
return 1;
}
void GeomFill_Fixed::Intervals(TColStd_Array1OfReal& T,
const GeomAbs_Shape) const
{
T(T.Lower()) = - Precision::Infinite();
T(T.Upper()) = Precision::Infinite();
}
void GeomFill_Fixed::GetAverageLaw(gp_Vec& ATangent,
gp_Vec& ANormal,
gp_Vec& ABiNormal)
{
ATangent = T;
ANormal = N;
ABiNormal = B;
}
Standard_Boolean GeomFill_Fixed::IsConstant() const
{
return Standard_True;
}

179
src/GeomFill/GeomFill_Frenet.cdl Executable file
View File

@@ -0,0 +1,179 @@
-- File: GeomFill_Frenet.cdl
-- Created: Fri Dec 19 11:57:17 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
class Frenet from GeomFill
inherits TrihedronLaw from GeomFill
---Purpose: Defined Frenet Trihedron Law
uses
HCurve from Adaptor3d,
Shape from GeomAbs,
Array1OfReal from TColStd,
Pnt from gp,
Vec from gp,
HArray1OfReal from TColStd,
HArray1OfBoolean from TColStd
raises
OutOfRange, ConstructionError
is
Create
returns Frenet from GeomFill
raises ConstructionError;
Copy(me)
returns TrihedronLaw from GeomFill
is redefined;
Init(me: mutable)
is static;
SetCurve(me : mutable; C : HCurve from Adaptor3d)
is redefined;
--
--
--========== To compute Location and derivatives Location
--
D0(me : mutable;
Param: Real;
Tangent : out Vec from gp;
Normal : out Vec from gp;
BiNormal : out Vec from gp)
---Purpose: compute Triedrhon on curve at parameter <Param>
returns Boolean is redefined;
D1(me : mutable;
Param: Real;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp)
---Purpose: compute Triedrhon and derivative Trihedron on curve
-- at parameter <Param>
-- Warning : It used only for C1 or C2 aproximation
returns Boolean
is redefined;
D2(me : mutable;
Param: Real;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
D2Tangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
D2Normal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp;
D2BiNormal : out Vec from gp)
---Purpose: compute Trihedron on curve
-- first and seconde derivatives.
-- Warning : It used only for C2 aproximation
returns Boolean
is redefined;
--
-- =================== Management of continuity ===================
--
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>.
-- May be one if Continuity(me) >= <S>
returns Integer is redefined;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is redefined;
-- =================== To help computation of Tolerance ===============
GetAverageLaw(me : mutable;
ATangent : out Vec from gp;
ANormal : out Vec from gp;
ABiNormal : out Vec from gp)
---Purpose: Get average value of Tangent(t) and Normal(t) it is usfull to
-- make fast approximation of rational surfaces.
is redefined;
-- =================== To help Particular case ===============
IsConstant(me)
---Purpose: Say if the law is Constant.
returns Boolean
is redefined;
IsOnlyBy3dCurve(me)
---Purpose: Return True.
returns Boolean
is redefined;
IsSingular(me; U: Real; Index: out Integer)
returns Boolean
is private;
DoSingular(me: mutable; U: Real; Index: Integer;
Tangent, BiNormal: out Vec from gp;
n, k, TFlag, BNFlag: out Integer)
returns Boolean
is private;
SingularD0(me : mutable;
Param: Real; Index: Integer;
Tangent : out Vec from gp;
Normal : out Vec from gp;
BiNormal : out Vec from gp)
---Purpose: computes Triedrhon on curve at parameter <Param>
returns Boolean
is private;
SingularD1(me : mutable;
Param: Real; Index: Integer;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp)
---Purpose: computes Triedrhon and derivative Trihedron on curve
-- at parameter <Param>
-- Warning : It used only for C1 or C2 aproximation
returns Boolean
is private;
SingularD2(me : mutable;
Param: Real; Index: Integer;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
D2Tangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
D2Normal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp;
D2BiNormal : out Vec from gp)
---Purpose: computes Trihedron on curve
-- first and seconde derivatives.
-- Warning : It used only for C2 aproximation
returns Boolean
is private;
fields
P : Pnt from gp;
mySngl : HArray1OfReal from TColStd;
mySnglLen : HArray1OfReal from TColStd;
isSngl : Boolean from Standard; -- True if there is some
-- singular points
end Frenet;

741
src/GeomFill/GeomFill_Frenet.cxx Executable file
View File

@@ -0,0 +1,741 @@
// File: GeomFill_Frenet.cxx
// Created: Thu Jan 22 09:12:54 1998
// Author: Philippe MANGIN/Roman BORISOV
// <pmn@sgi29>
#include <GeomFill_Frenet.ixx>
#include <GeomAbs_CurveType.hxx>
#include <Adaptor3d_HCurve.hxx>
#include <Precision.hxx>
#include <GeomLib.hxx>
#include <GeomFill_SnglrFunc.hxx>
#include <Extrema_ExtPC.hxx>
#include <TColStd_HArray1OfBoolean.hxx>
#include <SortTools_QuickSortOfReal.hxx>
#include <TCollection_CompareOfReal.hxx>
#include <TColgp_SequenceOfPnt2d.hxx>
#define NullTol 1.e-10
#define MaxSingular 1.e-5
//=======================================================================
//function : FDeriv
//purpose : computes (F/|F|)'
//=======================================================================
static gp_Vec FDeriv(const gp_Vec& F, const gp_Vec& DF)
{
Standard_Real Norma = F.Magnitude();
gp_Vec Result = (DF - F*(F*DF)/(Norma*Norma))/Norma;
return Result;
}
//=======================================================================
//function : DDeriv
//purpose : computes (F/|F|)''
//=======================================================================
static gp_Vec DDeriv(const gp_Vec& F, const gp_Vec& DF, const gp_Vec& D2F)
{
Standard_Real Norma = F.Magnitude();
gp_Vec Result = (D2F - 2*DF*(F*DF)/(Norma*Norma))/Norma -
F*((DF.SquareMagnitude() + F*D2F
- 3*(F*DF)*(F*DF)/(Norma*Norma))/(Norma*Norma*Norma));
return Result;
}
//=======================================================================
//function : GeomFill_Frenet
//purpose :
//=======================================================================
GeomFill_Frenet::GeomFill_Frenet()
{
}
//=======================================================================
//function : Copy
//purpose :
//=======================================================================
Handle(GeomFill_TrihedronLaw) GeomFill_Frenet::Copy() const
{
Handle(GeomFill_Frenet) copy = new (GeomFill_Frenet)();
if (!myCurve.IsNull()) copy->SetCurve(myCurve);
return copy;
}
//=======================================================================
//function : SetCurve
//purpose :
//=======================================================================
void GeomFill_Frenet::SetCurve(const Handle(Adaptor3d_HCurve)& C)
{
GeomFill_TrihedronLaw::SetCurve(C);
if (! C.IsNull()) {
GeomAbs_CurveType type;
type = C->GetType();
switch (type) {
case GeomAbs_Circle:
case GeomAbs_Ellipse:
case GeomAbs_Hyperbola:
case GeomAbs_Parabola:
case GeomAbs_Line:
{
// No probleme
isSngl = Standard_False;
}
default :
{
// We have to search singulaties
Init();
}
}
}
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_Frenet::Init()
{
Standard_Integer i, j;
GeomFill_SnglrFunc Func(myCurve);
Standard_Real TolF = 1.0e-10, Tol = 10*TolF, Tol2 = Tol * Tol,
PTol = Precision::PConfusion();
// We want to determine if the curve has linear segments
Standard_Integer NbIntC2 = myCurve->NbIntervals(GeomAbs_C2);
Handle(TColStd_HArray1OfReal) myC2Disc =
new TColStd_HArray1OfReal(1, NbIntC2 + 1);
Handle(TColStd_HArray1OfBoolean) IsLin =
new TColStd_HArray1OfBoolean(1, NbIntC2);
Handle(TColStd_HArray1OfBoolean) IsConst =
new TColStd_HArray1OfBoolean(1, NbIntC2);
TColStd_Array1OfReal AveFunc(1, NbIntC2);
myCurve->Intervals(myC2Disc->ChangeArray1(), GeomAbs_C2);
Standard_Integer NbControl = 10;
Standard_Real Step, Average = 0, modulus;
gp_Pnt C, C1;
for(i = 1; i <= NbIntC2; i++) {
Step = (myC2Disc->Value(i+1) - myC2Disc->Value(i))/NbControl;
IsLin->ChangeValue(i) = Standard_True;
IsConst->ChangeValue(i) = Standard_True;
for(j = 1; j <= NbControl; j++) {
Func.D0(myC2Disc->Value(i) + (j-1)*Step, C);
if(j == 1) C1 = C;
modulus = C.XYZ().Modulus();
if(modulus > Tol) {
IsLin->ChangeValue(i) = Standard_False;
}
Average += modulus;
if(IsConst->Value(i)) {
if(Abs(C.X() - C1.X()) > Tol ||
Abs(C.Y() - C1.Y()) > Tol ||
Abs(C.Z() - C1.Z()) > Tol) {
IsConst->ChangeValue(i) = Standard_False;
}
}
}
AveFunc(i) = Average/NbControl;
}
// Here we are looking for singularities
TColStd_SequenceOfReal * SeqArray = new TColStd_SequenceOfReal[ NbIntC2 ];
TColStd_SequenceOfReal SnglSeq;
// Standard_Real Value2, preValue=1.e200, t;
Standard_Real Value2, t;
Extrema_ExtPC Ext;
gp_Pnt Origin(0, 0, 0);
for(i = 1; i <= NbIntC2; i++) {
if (!IsLin->Value(i) && !IsConst->Value(i))
{
Func.SetRatio(1./AveFunc(i)); // Normalization
Ext.Initialize(Func, myC2Disc->Value(i), myC2Disc->Value(i+1), TolF);
Ext.Perform(Origin);
if(Ext.IsDone() && Ext.NbExt() != 0)
{
for(j = 1; j <= Ext.NbExt(); j++)
{
Value2 = Ext.SquareDistance(j);
if(Value2 < Tol2)
{
t = Ext.Point(j).Parameter();
SeqArray[i-1].Append(t);
}
}
}
// sorting
if(SeqArray[i-1].Length() != 0) {
TColStd_Array1OfReal anArray( 1, SeqArray[i-1].Length() );
for (j = 1; j <= anArray.Length(); j++)
anArray(j) = SeqArray[i-1](j);
TCollection_CompareOfReal Compar;
SortTools_QuickSortOfReal::Sort( anArray, Compar);
for (j = 1; j <= anArray.Length(); j++)
SeqArray[i-1](j) = anArray(j);
}
}
}
//Filling SnglSeq by first sets of roots
for(i = 0; i < NbIntC2; i++)
for (j = 1; j <= SeqArray[i].Length(); j++)
SnglSeq.Append( SeqArray[i](j) );
//Extrema works bad, need to pass second time
for(i = 0; i < NbIntC2; i++)
if (! SeqArray[i].IsEmpty())
{
SeqArray[i].Prepend( myC2Disc->Value(i+1) );
SeqArray[i].Append( myC2Disc->Value(i+2) );
Func.SetRatio(1./AveFunc(i+1)); // Normalization
for (j = 1; j < SeqArray[i].Length(); j++)
if (SeqArray[i](j+1) - SeqArray[i](j) > PTol)
{
Ext.Initialize(Func, SeqArray[i](j), SeqArray[i](j+1), TolF);
Ext.Perform(Origin);
if(Ext.IsDone())
{
for(Standard_Integer k = 1; k <= Ext.NbExt(); k++)
{
Value2 = Ext.SquareDistance(k);
if(Value2 < Tol2)
{
t = Ext.Point(k).Parameter();
if (t-SeqArray[i](j) > PTol && SeqArray[i](j+1)-t > PTol)
SnglSeq.Append(t);
}
}
}
}
}
delete [] SeqArray;
if(SnglSeq.Length() > 0) {
// sorting
TColStd_Array1OfReal anArray( 1, SnglSeq.Length() );
for (i = 1; i <= SnglSeq.Length(); i++)
anArray(i) = SnglSeq(i);
TCollection_CompareOfReal Compar;
SortTools_QuickSortOfReal::Sort( anArray, Compar );
for (i = 1; i <= SnglSeq.Length(); i++)
SnglSeq(i) = anArray(i);
// discard repeating elements
Standard_Boolean found = Standard_True;
j = 1;
while (found)
{
found = Standard_False;
for (i = j; i < SnglSeq.Length(); i++)
if (SnglSeq(i+1) - SnglSeq(i) <= PTol)
{
SnglSeq.Remove(i+1);
j = i;
found = Standard_True;
break;
}
}
mySngl = new TColStd_HArray1OfReal(1, SnglSeq.Length());
for(i = 1; i <= mySngl->Length(); i++)
mySngl->ChangeValue(i) = SnglSeq(i);
// computation of length of singular interval
mySnglLen = new TColStd_HArray1OfReal(1, mySngl->Length());
gp_Vec SnglDer, SnglDer2;
Standard_Real norm;
for(i = 1; i <= mySngl->Length(); i++) {
Func.D2(mySngl->Value(i), C, SnglDer, SnglDer2);
if ((norm = SnglDer.Magnitude()) > gp::Resolution())
mySnglLen->ChangeValue(i) = Min(NullTol/norm, MaxSingular);
else if ((norm = SnglDer2.Magnitude()) > gp::Resolution())
mySnglLen->ChangeValue(i) = Min(Sqrt(2*NullTol/norm), MaxSingular);
else mySnglLen->ChangeValue(i) = MaxSingular;
}
#if DEB
for(i = 1; i <= mySngl->Length(); i++) {
cout<<"Sngl("<<i<<") = "<<mySngl->Value(i)<<" Length = "<<mySnglLen->Value(i)<<endl;
}
#endif
if(mySngl->Length() > 1) {
// we have to merge singular points that have common parts of singular intervals
TColgp_SequenceOfPnt2d tmpSeq;
tmpSeq.Append(gp_Pnt2d(mySngl->Value(1), mySnglLen->Value(1)));
Standard_Real U11, U12, U21, U22;
for(i = 2; i<= mySngl->Length(); i++) {
U12 = tmpSeq.Last().X() + tmpSeq.Last().Y();
U21 = mySngl->Value(i) - mySnglLen->Value(i);
if(U12 >= U21) {
U11 = tmpSeq.Last().X() - tmpSeq.Last().Y();
U22 = mySngl->Value(i) + mySnglLen->Value(i);
tmpSeq.ChangeValue(tmpSeq.Length()) = gp_Pnt2d((U11 + U22)/2, (U22 - U11)/2);
}
else tmpSeq.Append(gp_Pnt2d(mySngl->Value(i), mySnglLen->Value(i)));
}
mySngl = new TColStd_HArray1OfReal(1, tmpSeq.Length());
mySnglLen = new TColStd_HArray1OfReal(1, tmpSeq.Length());
for(i = 1; i <= mySngl->Length(); i++) {
mySngl->ChangeValue(i) = tmpSeq(i).X();
mySnglLen->ChangeValue(i) = tmpSeq(i).Y();
}
}
#if DEB
cout<<"After merging"<<endl;
for(i = 1; i <= mySngl->Length(); i++) {
cout<<"Sngl("<<i<<") = "<<mySngl->Value(i)<<" Length = "<<mySnglLen->Value(i)<<endl;
}
#endif
isSngl = Standard_True;
}
else isSngl = Standard_False;
}
//=======================================================================
//function : D0
//purpose :
//=======================================================================
Standard_Boolean GeomFill_Frenet::D0(const Standard_Real Param,
gp_Vec& Tangent,
gp_Vec& Normal,
gp_Vec& BiNormal)
{
Standard_Real norm;
Standard_Integer Index;
if(IsSingular(Param, Index))
if (SingularD0(Param, Index, Tangent, Normal, BiNormal))
return Standard_True;
myTrimmed->D2(Param, P, Tangent, BiNormal);
Tangent.Normalize();
BiNormal = Tangent.Crossed(BiNormal);
norm = BiNormal.Magnitude();
if (norm <= gp::Resolution()) {
gp_Ax2 Axe (gp_Pnt(0,0,0), Tangent);
BiNormal.SetXYZ(Axe.YDirection().XYZ());
}
else BiNormal.Normalize();
Normal = BiNormal;
Normal.Cross(Tangent);
return Standard_True;
}
//=======================================================================
//function : D1
//purpose :
//=======================================================================
Standard_Boolean GeomFill_Frenet::D1(const Standard_Real Param,
gp_Vec& Tangent,
gp_Vec& DTangent,
gp_Vec& Normal,
gp_Vec& DNormal,
gp_Vec& BiNormal,
gp_Vec& DBiNormal)
{
Standard_Integer Index;
if(IsSingular(Param, Index))
if (SingularD1(Param, Index, Tangent, DTangent, Normal, DNormal, BiNormal, DBiNormal))
return Standard_True;
// Standard_Real Norma;
gp_Vec DC1, DC2, DC3;
myTrimmed->D3(Param, P, DC1, DC2, DC3);
Tangent = DC1.Normalized();
//if (DC2.Magnitude() <= NullTol || Tangent.Crossed(DC2).Magnitude() <= NullTol) {
if (Tangent.Crossed(DC2).Magnitude() <= gp::Resolution()) {
gp_Ax2 Axe (gp_Pnt(0,0,0), Tangent);
Normal.SetXYZ(Axe.XDirection().XYZ());
BiNormal.SetXYZ(Axe.YDirection().XYZ());
DTangent.SetCoord(0,0,0);
DNormal.SetCoord(0,0,0);
DBiNormal.SetCoord(0,0,0);
return Standard_True;
}
else
BiNormal = Tangent.Crossed(DC2).Normalized();
Normal = BiNormal.Crossed(Tangent);
DTangent = FDeriv(DC1, DC2);
gp_Vec instead_DC1, instead_DC2;
instead_DC1 = Tangent.Crossed(DC2);
instead_DC2 = DTangent.Crossed(DC2) + Tangent.Crossed(DC3);
DBiNormal = FDeriv(instead_DC1, instead_DC2);
DNormal = DBiNormal.Crossed(Tangent) + BiNormal.Crossed(DTangent);
return Standard_True;
}
//=======================================================================
//function : D2
//purpose :
//=======================================================================
Standard_Boolean GeomFill_Frenet::D2(const Standard_Real Param,
gp_Vec& Tangent,
gp_Vec& DTangent,
gp_Vec& D2Tangent,
gp_Vec& Normal,
gp_Vec& DNormal,
gp_Vec& D2Normal,
gp_Vec& BiNormal,
gp_Vec& DBiNormal,
gp_Vec& D2BiNormal)
{
Standard_Integer Index;
if(IsSingular(Param, Index))
if(SingularD2(Param, Index, Tangent, DTangent, D2Tangent,
Normal, DNormal, D2Normal,
BiNormal, DBiNormal, D2BiNormal))
return Standard_True;
// Standard_Real Norma;
gp_Vec DC1, DC2, DC3, DC4;
myTrimmed->D3(Param, P, DC1, DC2, DC3);
DC4 = myTrimmed->DN(Param, 4);
Tangent = DC1.Normalized();
//if (DC2.Magnitude() <= NullTol || Tangent.Crossed(DC2).Magnitude() <= NullTol) {
if (Tangent.Crossed(DC2).Magnitude() <= gp::Resolution()) {
gp_Ax2 Axe (gp_Pnt(0,0,0), Tangent);
Normal.SetXYZ(Axe.XDirection().XYZ());
BiNormal.SetXYZ(Axe.YDirection().XYZ());
DTangent.SetCoord(0,0,0);
DNormal.SetCoord(0,0,0);
DBiNormal.SetCoord(0,0,0);
D2Tangent.SetCoord(0,0,0);
D2Normal.SetCoord(0,0,0);
D2BiNormal.SetCoord(0,0,0);
return Standard_True;
}
else
BiNormal = Tangent.Crossed(DC2).Normalized();
Normal = BiNormal.Crossed(Tangent);
DTangent = FDeriv(DC1, DC2);
D2Tangent = DDeriv(DC1, DC2, DC3);
gp_Vec instead_DC1, instead_DC2, instead_DC3;
instead_DC1 = Tangent.Crossed(DC2);
instead_DC2 = DTangent.Crossed(DC2) + Tangent.Crossed(DC3);
instead_DC3 = D2Tangent.Crossed(DC2) + 2*DTangent.Crossed(DC3) + Tangent.Crossed(DC4);
DBiNormal = FDeriv(instead_DC1, instead_DC2);
D2BiNormal = DDeriv(instead_DC1, instead_DC2, instead_DC3);
DNormal = DBiNormal.Crossed(Tangent) + BiNormal.Crossed(DTangent);
D2Normal = D2BiNormal.Crossed(Tangent) + 2*DBiNormal.Crossed(DTangent) + BiNormal.Crossed(D2Tangent);
return Standard_True;
}
//=======================================================================
//function : NbIntervals
//purpose :
//=======================================================================
Standard_Integer GeomFill_Frenet::NbIntervals(const GeomAbs_Shape S) const
{
GeomAbs_Shape tmpS = GeomAbs_C0;
Standard_Integer NbTrimmed;
switch (S) {
case GeomAbs_C0: tmpS = GeomAbs_C2; break;
case GeomAbs_C1: tmpS = GeomAbs_C3; break;
case GeomAbs_C2:
case GeomAbs_C3:
case GeomAbs_CN: tmpS = GeomAbs_CN; break;
default: Standard_OutOfRange::Raise();
}
NbTrimmed = myCurve->NbIntervals(tmpS);
if (!isSngl) return NbTrimmed;
TColStd_Array1OfReal TrimInt(1, NbTrimmed + 1);
myCurve->Intervals(TrimInt, tmpS);
TColStd_SequenceOfReal Fusion;
GeomLib::FuseIntervals(TrimInt, mySngl->Array1(), Fusion);
return Fusion.Length() - 1;
}
//=======================================================================
//function : Intervals
//purpose :
//=======================================================================
void GeomFill_Frenet::Intervals(TColStd_Array1OfReal& T,
const GeomAbs_Shape S) const
{
GeomAbs_Shape tmpS = GeomAbs_C0;
Standard_Integer NbTrimmed;
switch (S) {
case GeomAbs_C0: tmpS = GeomAbs_C2; break;
case GeomAbs_C1: tmpS = GeomAbs_C3; break;
case GeomAbs_C2:
case GeomAbs_C3:
case GeomAbs_CN: tmpS = GeomAbs_CN; break;
default: Standard_OutOfRange::Raise();
}
if (!isSngl) {
myCurve->Intervals(T, tmpS);
return;
}
NbTrimmed = myCurve->NbIntervals(tmpS);
TColStd_Array1OfReal TrimInt(1, NbTrimmed + 1);
myCurve->Intervals(TrimInt, tmpS);
TColStd_SequenceOfReal Fusion;
GeomLib::FuseIntervals(TrimInt, mySngl->Array1(), Fusion);
for (Standard_Integer i = 1; i <= Fusion.Length(); i++)
T.ChangeValue(i) = Fusion.Value(i);
}
void GeomFill_Frenet::GetAverageLaw(gp_Vec& ATangent,
gp_Vec& ANormal,
gp_Vec& ABiNormal)
{
Standard_Integer Num = 20; //order of digitalization
gp_Vec T, N, BN;
ATangent = gp_Vec(0, 0, 0);
ANormal = gp_Vec(0, 0, 0);
ABiNormal = gp_Vec(0, 0, 0);
Standard_Real Step = (myTrimmed->LastParameter() -
myTrimmed->FirstParameter()) / Num;
Standard_Real Param;
for (Standard_Integer i = 0; i <= Num; i++) {
Param = myTrimmed->FirstParameter() + i*Step;
if (Param > myTrimmed->LastParameter()) Param = myTrimmed->LastParameter();
D0(Param, T, N, BN);
ATangent += T;
ANormal += N;
ABiNormal += BN;
}
ATangent /= Num + 1;
ANormal /= Num + 1;
ATangent.Normalize();
ABiNormal = ATangent.Crossed(ANormal).Normalized();
ANormal = ABiNormal.Crossed(ATangent);
}
//=======================================================================
//function : IsConstant
//purpose :
//=======================================================================
Standard_Boolean GeomFill_Frenet::IsConstant() const
{
return (myCurve->GetType() == GeomAbs_Line);
}
//=======================================================================
//function : IsOnlyBy3dCurve
//purpose :
//=======================================================================
Standard_Boolean GeomFill_Frenet::IsOnlyBy3dCurve() const
{
return Standard_True;
}
//=======================================================================
//function : IsSingular
//purpose :
//=======================================================================
Standard_Boolean GeomFill_Frenet::IsSingular(const Standard_Real U, Standard_Integer& Index) const
{
Standard_Integer i;
if(!isSngl) return Standard_False;
for(i = 1; i <= mySngl->Length(); i++) {
if (Abs(U - mySngl->Value(i)) < mySnglLen->Value(i)) {
Index = i;
return Standard_True;
}
}
return Standard_False;
}
//=======================================================================
//function : DoSingular
//purpose :
//=======================================================================
Standard_Boolean GeomFill_Frenet::DoSingular(const Standard_Real U,
const Standard_Integer Index,
gp_Vec& Tangent,
gp_Vec& BiNormal,
Standard_Integer& n,
Standard_Integer& k,
Standard_Integer& TFlag,
Standard_Integer& BNFlag)
{
Standard_Integer i, MaxN = 20;
Standard_Real h;
h = 2*mySnglLen->Value(Index);
Standard_Real A, B;
gp_Vec T, N, BN;
TFlag = 1;
BNFlag = 1;
GetInterval(A, B);
if (U >= (A + B)/2) h = -h;
for(i = 1; i <= MaxN; i++) {
Tangent = myTrimmed->DN(U, i);
if(Tangent.Magnitude() > Precision::Confusion()) break;
}
if (i > MaxN) return Standard_False;
Tangent.Normalize();
n = i;
i++;
for(; i <= MaxN; i++) {
BiNormal = Tangent.Crossed(myTrimmed->DN(U, i));
Standard_Real magn = BiNormal.Magnitude();
if (magn > Precision::Confusion())
{
//modified by jgv, 12.08.03 for OCC605 ////
gp_Vec NextBiNormal = Tangent.Crossed(myTrimmed->DN(U, i+1));
if (NextBiNormal.Magnitude() > magn)
{
i++;
BiNormal = NextBiNormal;
}
///////////////////////////////////////////
break;
}
}
if (i > MaxN) return Standard_False;
BiNormal.Normalize();
k = i;
D0(U + h, T, N, BN);
if(Tangent.Angle(T) > PI/2) TFlag = -1;
if(BiNormal.Angle(BN) > PI/2) BNFlag = -1;
return Standard_True;
}
Standard_Boolean GeomFill_Frenet::SingularD0(const Standard_Real Param,
const Standard_Integer Index,
gp_Vec& Tangent,
gp_Vec& Normal,
gp_Vec& BiNormal)
{
Standard_Integer n, k, TFlag, BNFlag;
if(!DoSingular(Param, Index, Tangent, BiNormal,
n, k, TFlag, BNFlag)) return Standard_False;
Tangent *= TFlag;
BiNormal *= BNFlag;
Normal = BiNormal;
Normal.Cross(Tangent);
return Standard_True;
}
Standard_Boolean GeomFill_Frenet::SingularD1(const Standard_Real Param,
const Standard_Integer Index,
gp_Vec& Tangent,gp_Vec& DTangent,
gp_Vec& Normal,gp_Vec& DNormal,
gp_Vec& BiNormal,gp_Vec& DBiNormal)
{
Standard_Integer n, k, TFlag, BNFlag;
if(!DoSingular(Param, Index, Tangent, BiNormal, n, k, TFlag, BNFlag)) return Standard_False;
gp_Vec F, DF, Dtmp;
F = myTrimmed->DN(Param, n);
DF = myTrimmed->DN(Param, n+1);
DTangent = FDeriv(F, DF);
Dtmp = myTrimmed->DN(Param, k);
F = Tangent.Crossed(Dtmp);
DF = DTangent.Crossed(Dtmp) + Tangent.Crossed(myTrimmed->DN(Param, k+1));
DBiNormal = FDeriv(F, DF);
if(TFlag < 0) {
Tangent = -Tangent;
DTangent = -DTangent;
}
if(BNFlag < 0) {
BiNormal = -BiNormal;
DBiNormal = -DBiNormal;
}
Normal = BiNormal.Crossed(Tangent);
DNormal = DBiNormal.Crossed(Tangent) + BiNormal.Crossed(DTangent);
return Standard_True;
}
Standard_Boolean GeomFill_Frenet::SingularD2(const Standard_Real Param,
const Standard_Integer Index,
gp_Vec& Tangent,
gp_Vec& DTangent,
gp_Vec& D2Tangent,
gp_Vec& Normal,
gp_Vec& DNormal,
gp_Vec& D2Normal,
gp_Vec& BiNormal,
gp_Vec& DBiNormal,
gp_Vec& D2BiNormal)
{
Standard_Integer n, k, TFlag, BNFlag;
if(!DoSingular(Param, Index, Tangent, BiNormal, n, k, TFlag, BNFlag))
return Standard_False;
gp_Vec F, DF, D2F, Dtmp1, Dtmp2;
F = myTrimmed->DN(Param, n);
DF = myTrimmed->DN(Param, n+1);
D2F = myTrimmed->DN(Param, n+2);
DTangent = FDeriv(F, DF);
D2Tangent = DDeriv(F, DF, D2F);
Dtmp1 = myTrimmed->DN(Param, k);
Dtmp2 = myTrimmed->DN(Param, k+1);
F = Tangent.Crossed(Dtmp1);
DF = DTangent.Crossed(Dtmp1) + Tangent.Crossed(Dtmp2);
D2F = D2Tangent.Crossed(Dtmp1) + 2*DTangent.Crossed(Dtmp2) +
Tangent.Crossed(myTrimmed->DN(Param, k+2));
DBiNormal = FDeriv(F, DF);
D2BiNormal = DDeriv(F, DF, D2F);
if(TFlag < 0) {
Tangent = -Tangent;
DTangent = -DTangent;
D2Tangent = -D2Tangent;
}
if(BNFlag < 0) {
BiNormal = -BiNormal;
DBiNormal = -DBiNormal;
D2BiNormal = -D2BiNormal;
}
Normal = BiNormal.Crossed(Tangent);
DNormal = DBiNormal.Crossed(Tangent) + BiNormal.Crossed(DTangent);
D2Normal = D2BiNormal.Crossed(Tangent) + 2*DBiNormal.Crossed(DTangent) + BiNormal.Crossed(D2Tangent);
return Standard_True;
}

View File

@@ -0,0 +1,109 @@
-- File: GeomFill_FunctionDraft.cdl
-- Created: Mon Apr 27 10:53:22 1998
-- Author: Stephanie HUMEAU
-- <shu@sun17>
---Copyright: Matra Datavision 1998
private class FunctionDraft from GeomFill
inherits FunctionSetWithDerivatives from math
uses
Vector from math,
Matrix from math,
HSurface from Adaptor3d,
HCurve from Adaptor3d,
Vec from gp,
Tensor from GeomFill
is
Create(S : HSurface from Adaptor3d ; C : HCurve from Adaptor3d)
returns FunctionDraft from GeomFill ;
NbVariables(me)
---Purpose: returns the number of variables of the function.
returns Integer is redefined;
NbEquations(me)
---Purpose: returns the number of equations of the function.
returns Integer is redefined;
Value(me: in out; X: Vector; F: out Vector)
---Purpose: computes the values <F> of the Functions for the
-- variable <X>.
-- Returns True if the computation was done successfully,
-- False otherwise.
returns Boolean is redefined;
Derivatives(me: in out; X: Vector; D: out Matrix)
---Purpose: returns the values <D> of the derivatives for the
-- variable <X>.
-- Returns True if the computation was done successfully,
-- False otherwise.
returns Boolean is redefined;
Values(me: in out; X: Vector; F: out Vector; D: out Matrix)
---Purpose: returns the values <F> of the functions and the derivatives
-- <D> for the variable <X>.
-- Returns True if the computation was done successfully,
-- False otherwise.
returns Boolean is redefined;
DerivT(me: in out;
C : HCurve from Adaptor3d;
Param : Real from Standard;
W : Real from Standard;
dN : Vec from gp;
teta : Real;
F: out Vector)
---Purpose: returns the values <F> of the T derivatives for
-- the parameter Param .
returns Boolean is static;
Deriv2T(me: in out;
C : HCurve from Adaptor3d;
Param : Real from Standard;
W : Real from Standard;
d2N : Vec from gp;
teta : Real;
F: out Vector)
---Purpose: returns the values <F> of the T2 derivatives for
-- the parameter Param .
returns Boolean is static;
DerivTX(me: in out;
dN : Vec from gp;
teta : Real;
D: out Matrix)
---Purpose: returns the values <D> of the TX derivatives for
-- the parameter Param .
returns Boolean is static;
Deriv2X(me: in out;
X : Vector from math;
T: out Tensor)
---Purpose: returns the values <T> of the X2 derivatives for
-- the parameter Param .
returns Boolean is static;
fields
TheCurve : HCurve from Adaptor3d;
TheSurface : HSurface from Adaptor3d;
end FunctionDraft;

View File

@@ -0,0 +1,213 @@
// File: GeomFill_FunctionDraft.cxx
// Created: Mon Apr 27 11:09:42 1998
// Author: Stephanie HUMEAU
// <shu@sun17>
#include <GeomFill_FunctionDraft.ixx>
#include <GeomAdaptor_HSurface.hxx>
#include <GeomAdaptor_HCurve.hxx>
//#include <Precision.hxx>
#include <gp_Pnt.hxx>
//*******************************************************
// Calcul de la valeur de la fonction :
// G(w(t)) - S(u(t),v(t)) = 0
// ou G = generatrice et S = surface d'arret
// et de ses derivees
//*******************************************************
//*******************************************************
// Function : FunctionDraft
// Purpose : Initialisation de la section et de la surface d'arret
//*******************************************************
GeomFill_FunctionDraft::GeomFill_FunctionDraft
(const Handle(Adaptor3d_HSurface)& S, const Handle(Adaptor3d_HCurve)& C)
{
TheCurve = C ;
TheSurface = S;
}
//*******************************************************
// Function : NbVariables (t, u, v)
// Purpose :
//*******************************************************
Standard_Integer GeomFill_FunctionDraft::NbVariables()const
{
return 3;
}
//*******************************************************
// Function : NbEquations
// Purpose :
//*******************************************************
Standard_Integer GeomFill_FunctionDraft::NbEquations()const
{
return 3;
}
//*******************************************************
// Function : Value
// Purpose : calcul of the value of the function at <X>
//*******************************************************
Standard_Boolean GeomFill_FunctionDraft::Value(const math_Vector& X,
math_Vector& F)
{
gp_Pnt P,P1;
TheCurve->D0(X(1), P);
TheSurface->D0(X(2), X(3), P1);
F(1) = P.Coord(1) - P1.Coord(1);
F(2) = P.Coord(2) - P1.Coord(2);
F(3) = P.Coord(3) - P1.Coord(3);
return Standard_True;
}
//*******************************************************
// Function : Derivatives
// Purpose :calcul of the derivative of the function
//*******************************************************
Standard_Boolean GeomFill_FunctionDraft::Derivatives(const math_Vector& X,
math_Matrix& D)
{
Standard_Integer i;
gp_Pnt P,P1;
gp_Vec DP,DP1U,DP1V;
TheCurve->D1(X(1),P,DP);
TheSurface->D1(X(2),X(3),P1,DP1U,DP1V);
for (i=1;i<=3;i++)
{
D(i,1) = DP.Coord(i);
D(i,2) = -DP1U.Coord(i);
D(i,3) = -DP1V.Coord(i);
}
return Standard_True;
}
//*******************************************************
// Function : Values
// Purpose : calcul of the value and the derivative of the function
//*******************************************************
Standard_Boolean GeomFill_FunctionDraft::Values(const math_Vector& X,
math_Vector& F,
math_Matrix& D)
{
Standard_Integer i;
gp_Pnt P,P1;
gp_Vec DP,DP1U,DP1V;
TheCurve->D1(X(1),P,DP); //derivee de la generatrice
TheSurface->D1(X(2),X(3),P1,DP1U,DP1V); //derivee de la new surface
for (i=1;i<=3;i++)
{
F(i) = P.Coord(i) - P1.Coord(i);
D(i,1) = DP.Coord(i);
D(i,2) = -DP1U.Coord(i);
D(i,3) = -DP1V.Coord(i);
}
return Standard_True;
}
//*******************************************************
// Function : DerivT
// Purpose : calcul of the first derivative from t
//*******************************************************
Standard_Boolean GeomFill_FunctionDraft::DerivT(const Handle(Adaptor3d_HCurve)& C,
const Standard_Real Param,
const Standard_Real W,
const gp_Vec & dN,
const Standard_Real teta,
math_Vector& F)
{
gp_Pnt P;
gp_Vec DP;
C->D1(Param, P, DP); // derivee de la section
F(1) = DP.Coord(1) + W * dN.Coord(1) * Sin(teta);
F(2) = DP.Coord(2) + W * dN.Coord(2) * Sin(teta);
F(3) = DP.Coord(3) + W * dN.Coord(3) * Sin(teta);
return Standard_True;
}
//*******************************************************
// Function : Deriv2T
// Purpose : calcul of the second derivatice from t
//*******************************************************
Standard_Boolean GeomFill_FunctionDraft::Deriv2T(const Handle(Adaptor3d_HCurve)& C,
const Standard_Real Param,
const Standard_Real W,
const gp_Vec & d2N,
const Standard_Real teta,
math_Vector& F)
{
gp_Pnt P;
gp_Vec DP,D2P;
C->D2(Param, P, DP, D2P); // derivee de la section
F(1) = D2P.Coord(1) + W * d2N.Coord(1) * Sin(teta);
F(2) = D2P.Coord(2) + W * d2N.Coord(2) * Sin(teta);
F(3) = D2P.Coord(3) + W * d2N.Coord(3) * Sin(teta);
return Standard_True;
}
//*******************************************************
// Function : DerivTX
// Purpose : calcul of the second derivative from t and x
//*******************************************************
Standard_Boolean GeomFill_FunctionDraft::DerivTX(const gp_Vec & dN,
const Standard_Real teta,
math_Matrix& D)
{
// gp_Pnt P;
// gp_Vec DP,D2P;
Standard_Integer i;
for (i=1;i<=3;i++)
{
D(i,1) = dN.Coord(i)*Sin(teta); //derivee / W
D(i,2) = 0.; // derivee / U
D(i,3) = 0.; // derivee / V
}
return Standard_True;
}
//*******************************************************
// Function : Deriv2X
// Purpose : calcul of the second derivative from x
//*******************************************************
Standard_Boolean GeomFill_FunctionDraft::Deriv2X(const math_Vector & X,
GeomFill_Tensor& T)
{
gp_Pnt P;
gp_Vec DPu,DPv;
gp_Vec D2Pu, D2Pv, D2Puv;
Standard_Integer i;
TheSurface->D2(X(2), X(3), P, DPu, DPv, D2Pu, D2Pv, D2Puv);
T.Init(0.); // tenseur
for (i=1;i<=3;i++)
{
T(i,2,2) = -D2Pu.Coord(i);
T(i,3,2) = T(i,2,3) = -D2Puv.Coord(i);
T(i,3,3) = -D2Pv.Coord(i);
}
return Standard_True;
}

View File

@@ -0,0 +1,131 @@
-- File: GeomFill_FunctionGuide.cdl
-- Created: Thu Jul 9 09:29:32 1998
-- Author: Stephanie HUMEAU
-- <shu@sun17>
---Copyright: Matra Datavision 1998
private class FunctionGuide from GeomFill
inherits FunctionSetWithDerivatives from math
uses
Vector from math,
Matrix from math,
Surface from Geom,
Curve from Geom,
HCurve from Adaptor3d,
Vec from gp,
XYZ from gp,
Pnt from gp,
SectionLaw from GeomFill
is
Create(S : SectionLaw from GeomFill;
Guide : HCurve from Adaptor3d;
ParamOnLaw : Real = 0.0)
returns FunctionGuide from GeomFill ;
SetParam(me : in out;
Param : Real;
Centre : Pnt from gp;
Dir : XYZ from gp;
XDir : XYZ from gp)
is static;
NbVariables(me)
---Purpose: returns the number of variables of the function.
returns Integer is redefined;
NbEquations(me)
---Purpose: returns the number of equations of the function.
returns Integer is redefined;
Value(me: in out; X: Vector; F: out Vector)
---Purpose: computes the values <F> of the Functions for the
-- variable <X>.
-- Returns True if the computation was done successfully,
-- False otherwise.
returns Boolean is redefined;
Derivatives(me: in out; X: Vector; D: out Matrix)
---Purpose: returns the values <D> of the derivatives for the
-- variable <X>.
-- Returns True if the computation was done successfully,
-- False otherwise.
returns Boolean is redefined;
Values(me: in out; X: Vector; F: out Vector; D: out Matrix)
---Purpose: returns the values <F> of the functions and the derivatives
-- <D> for the variable <X>.
-- Returns True if the computation was done successfully,
-- False otherwise.
returns Boolean is redefined;
DerivT(me : in out;
X : Vector from math;
DCentre: XYZ from gp;
DDir : XYZ from gp;
DFDT : out Vector)
---Purpose: returns the values <F> of the T derivatives for
-- the parameter Param .
returns Boolean is static;
DSDT(me;
U, V : Real;
DCentre: XYZ from gp;
DDir : XYZ from gp;
DSDT : out Vec from gp)
is private;
Deriv2T(me: in out;
DCentre: XYZ from gp;
DDir : XYZ from gp;
DFDT, D2FT : out Vector)
---Purpose: returns the values <F> of the T2 derivatives for
-- the parameter Param .
returns Boolean is static;
-- DerivTX(me: in out;
-- Param : Real from Standard;
-- Param0 : Real from Standard;
-- R : Vector from math;
-- X0 : Vector from math;
-- D: out Matrix)
---Purpose: returns the values <D> of the TX derivatives for
-- the parameter Param .
-- returns Boolean is static;
-- Deriv2X(me: in out;
-- X : Vector from math;
-- T: out Tensor)
---Purpose: returns the values <T> of the X2 derivatives for
-- the parameter Param .
-- returns Boolean is static;
fields
TheGuide : HCurve from Adaptor3d;
TheLaw : SectionLaw from GeomFill;
isconst : Boolean;
TheCurve : Curve from Geom;
TheConst : Curve from Geom;
TheSurface: Surface from Geom;
First,Last: Real;
TheUonS : Real;
Centre : XYZ;
Dir : XYZ;
end FunctionGuide;

View File

@@ -0,0 +1,407 @@
// File: GeomFill_FunctionGuide.cxx
// Created: Thu Jul 9 09:30:26 1998
// Author: Stephanie HUMEAU
// <shu@sun17>
#include <GeomFill_FunctionGuide.ixx>
#include <GeomFill_SectionLaw.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_SurfaceOfRevolution.hxx>
#include <GeomAdaptor_HCurve.hxx>
#include <GeomTools.hxx>
#include <Precision.hxx>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
#include <gp_XYZ.hxx>
#include <gp_Dir.hxx>
#include <gp_Trsf.hxx>
#include <gp_Ax1.hxx>
#include <gp_Ax3.hxx>
#include <TColStd_HArray1OfInteger.hxx>
#include <TColStd_HArray1OfReal.hxx>
#include <TColgp_HArray1OfPnt.hxx>
//#include <Standard_NotImplemented.hxx>
//==============================================
// Calcul de la valeur de la fonction :
// G(w) - S(teta,v) = 0
// ou G : guide et S : surface de revolution
//==============================================
//==============================================
// Function : FunctionGuide
// Purpose : Initialisation de la section et de la surface d'arret
//==============================================
GeomFill_FunctionGuide::GeomFill_FunctionGuide
(const Handle(GeomFill_SectionLaw)& S,
const Handle(Adaptor3d_HCurve)& C,
const Standard_Real Param)
: TheGuide(C), TheLaw(S), TheUonS(Param)
{
Standard_Real Tol = Precision::Confusion();
if (TheLaw->IsConstant(Tol)) {
isconst = Standard_True;
TheConst = TheLaw->ConstantSection();
First = TheConst->FirstParameter();
Last = TheConst->LastParameter();
}
else {
isconst = Standard_False;
TheConst.Nullify();
}
TheCurve.Nullify();
}
//==============================================
// Function : SetParam
// Purpose : Initialisation de la surface de revolution
//==============================================
// void GeomFill_FunctionGuide::SetParam(const Standard_Real Param,
void GeomFill_FunctionGuide::SetParam(const Standard_Real ,
const gp_Pnt& C,
const gp_XYZ& D,
const gp_XYZ& DX)
{
Centre = C.XYZ();
Dir = D;
//repere fixe
gp_Ax3 Rep (gp::Origin(), gp::DZ(), gp::DX());
// calculer transfo entre triedre et Oxyz
gp_Dir B2 = DX;
gp_Ax3 RepTriedre(C, D, B2);
gp_Trsf Transfo;
Transfo.SetTransformation(RepTriedre, Rep);
if (isconst) {
TheCurve = new (Geom_TrimmedCurve)
(Handle(Geom_Curve)::DownCast(TheConst->Copy()),
First, Last);
}
else {
Standard_Integer NbPoles, NbKnots, Deg;
TheLaw->SectionShape(NbPoles, NbKnots, Deg);
TColStd_Array1OfInteger Mult(1,NbKnots);
TheLaw->Mults( Mult);
TColStd_Array1OfReal Knots(1,NbKnots);
TheLaw->Knots(Knots);
TColgp_Array1OfPnt Poles(1, NbPoles);
TColStd_Array1OfReal Weights(1, NbPoles);
TheLaw->D0(TheUonS, Poles, Weights);
if (TheLaw->IsRational())
TheCurve = new (Geom_BSplineCurve)
(Poles, Weights, Knots, Mult ,
Deg, TheLaw->IsUPeriodic());
else
TheCurve = new (Geom_BSplineCurve)
(Poles, Knots, Mult,
Deg, TheLaw->IsUPeriodic());
}
gp_Ax1 Axe(C, Dir);
TheCurve->Transform(Transfo);
TheSurface = new(Geom_SurfaceOfRevolution) (TheCurve, Axe);
}
//==============================================
// Function : NbVariables (w, u, v)
// Purpose :
//==============================================
Standard_Integer GeomFill_FunctionGuide::NbVariables()const
{
return 3;
}
//==============================================
// Function : NbEquations
// Purpose :
//==============================================
Standard_Integer GeomFill_FunctionGuide::NbEquations()const
{
return 3;
}
//==============================================
// Function : Value
// Purpose : calcul of the value of the function at <X>
//==============================================
Standard_Boolean GeomFill_FunctionGuide::Value(const math_Vector& X,
math_Vector& F)
{
gp_Pnt P,P1;
TheGuide->D0(X(1), P);
TheSurface->D0(X(2), X(3), P1);
F(1) = P.Coord(1) - P1.Coord(1);
F(2) = P.Coord(2) - P1.Coord(2);
F(3) = P.Coord(3) - P1.Coord(3);
return Standard_True;
}
//==============================================
// Function : Derivatives
// Purpose :calcul of the derivative of the function
//==============================================
Standard_Boolean GeomFill_FunctionGuide::Derivatives(const math_Vector& X,
math_Matrix& D)
{
gp_Pnt P,P1;
gp_Vec DP,DP1U,DP1V;
TheGuide->D1(X(1),P,DP);
TheSurface->D1(X(2),X(3),P1,DP1U,DP1V);
Standard_Integer i;
for (i=1;i<=3;i++)
{
D(i,1) = DP.Coord(i);
D(i,2) = -DP1U.Coord(i);
D(i,3) = -DP1V.Coord(i);
}// for
return Standard_True;
}
//==============================================
// Function : Values
// Purpose : calcul of the value and the derivative of the function
//==============================================
Standard_Boolean GeomFill_FunctionGuide::Values(const math_Vector& X,
math_Vector& F,
math_Matrix& D)
{
gp_Pnt P,P1;
gp_Vec DP,DP1U,DP1V;
TheGuide->D1(X(1),P,DP); //derivee de la generatrice
TheSurface->D1(X(2),X(3),P1,DP1U,DP1V); //derivee de la new surface
Standard_Integer i;
for (i=1;i<=3;i++)
{
F(i) = P.Coord(i) - P1.Coord(i);
D(i,1) = DP.Coord(i);
D(i,2) = -DP1U.Coord(i);
D(i,3) = -DP1V.Coord(i);
}// for
return Standard_True;
}
//==============================================
// Function : DerivT
// Purpose : calcul of the first derivative from t
//==============================================
Standard_Boolean GeomFill_FunctionGuide::DerivT(const math_Vector& X,
const gp_XYZ& DCentre,
const gp_XYZ& DDir,
math_Vector& F)
{
gp_Pnt P;
gp_Vec DS;
DSDT(X(2),X(3), DCentre,DDir, DS);
TheCurve->D0(X(1), P);
F(1) = P.Coord(1) - DS.Coord(1);
F(2) = P.Coord(2) - DS.Coord(2);
F(3) = P.Coord(3) - DS.Coord(3);
return Standard_True;
}
//=========================================================
// Function : DSDT
// Purpose : calcul de la derive de la surface /t en U, V
//=========================================================
void GeomFill_FunctionGuide::DSDT(const Standard_Real U,
const Standard_Real V,
const gp_XYZ& DC,
const gp_XYZ& DDir,
gp_Vec& DS) const
{
// C origine sur l'axe de revolution
// Vdir vecteur unitaire definissant la direction de l'axe de revolution
// Q(v) point de parametre V sur la courbe de revolution
// OM (u,v) = OC + CQ * Cos(U) + (CQ.Vdir)(1-Cos(U)) * Vdir +
// (Vdir^CQ)* Sin(U)
gp_Pnt Pc;
TheCurve->D0(V, Pc); //Q(v)
// if (!isconst)
gp_XYZ& Q = Pc.ChangeCoord(), DQ(0, 0, 0); //Q
if (!isconst) {
cout << "Not implemented" << endl;
}
Q.Subtract(Centre); //CQ
DQ -= DC;
gp_XYZ DVcrossCQ;
DVcrossCQ.SetLinearForm(DDir.Crossed (Q),
Dir.Crossed(DQ)); //Vdir^CQ
DVcrossCQ.Multiply (Sin(U)); //(Vdir^CQ)*Sin(U)
Standard_Real CosU = Cos(U);
gp_XYZ DVdotCQ;
DVdotCQ.SetLinearForm(DDir.Dot(Q) + Dir.Dot(DQ), Dir,
Dir.Dot(Q), DDir);//(CQ.Vdir)(1-Cos(U))Vdir
DVdotCQ.Add (DVcrossCQ); //addition des composantes
DQ.Multiply (CosU);
DQ.Add (DVdotCQ);
DQ.Add (DC);
DS.SetXYZ(DQ);
}
//=========================================================
// Function : Deriv2T
// Purpose : calcul of the second derivatice from t
//=========================================================
/* Standard_Boolean GeomFill_FunctionGuide::Deriv2T(const Standard_Real Param1,
const Standard_Real Param,
const Standard_Real Param0,
const math_Vector & R1,
const math_Vector & R,
const math_Vector & R0,
math_Vector& F)
{
math_Vector F1(1,3,0);
math_Vector F2(1,3,0);
DerivT(Param1, Param, R1, R, F1);
DerivT(Param, Param0, R, R0, F2);
Standard_Real h1 = Param - Param1;
Standard_Real h2 = Param0 - Param;
Standard_Integer i;
for (i=1;i<=3;i++)
F(i) = (F2(i) - F1(i)) / ((h2 + h1)/2);
return Standard_True;
}
//=========================================================
// Function : DerivTX
// Purpose : calcul of the second derivative from t and x
//=========================================================
Standard_Boolean GeomFill_FunctionGuide::DerivTX(const Standard_Real Param,
const Standard_Real Param0,
const math_Vector & R,
const math_Vector & X0,
math_Matrix& D)
{
gp_Pnt P1,P2;
gp_Vec DP1,DP2,DP2U,DP2V,DP1U,DP1V;
TheCurve->D1(R(1), P1, DP1); // guide
TheCurve->D1(X0(1), P2, DP2);
TheSurface->D1(R(2), R(3), P1, DP1U, DP1V); // surface
TheSurface->D1(X0(2), X0(3), P2, DP2U, DP2V); //derivee de la new surface
Standard_Real h = Param0 - Param;
Standard_Integer i;
for (i=1;i<=3;i++)
{
D(i,1) = (DP2.Coord(i) - DP1.Coord(i)) / h;
//D(i,2) = - (DP2U.Coord(i) - DP1U.Coord(i)) / h;
D(i,2) = - DP1U.Coord(i) * (X0(2)-R(2)) / h;
//D(i,3) = - (DP2V.Coord(i) - DP1V.Coord(i)) / h;
D(i,3) = - DP1V.Coord(i) * (X0(3)-R(3)) / h;
}// for
return Standard_True;
}
//=========================================================
// Function : Deriv2X
// Purpose : calcul of the second derivative from x
//=========================================================
Standard_Boolean GeomFill_FunctionGuide::Deriv2X(const math_Vector & X,
GeomFill_Tensor& T)
{
gp_Pnt P,P1;
gp_Vec DP,D2P,DPU,DPV;
gp_Vec D2PU, D2PV, D2PUV;
TheCurve->D2(X(1), P1, DP, D2P);
TheSurface->D2(X(2), X(3), P, DPU, DPV, D2PU, D2PV, D2PUV);
T.Init(0.); // tenseur
Standard_Integer i;
for (i=1;i<=3;i++)
{
T(i,1,1) = D2P.Coord(i);
T(i,2,2) = -D2PU.Coord(i);
T(i,3,2) = T(i,2,3) = -D2PUV.Coord(i);
T(i,3,3) = -D2PV.Coord(i);
}// for
return Standard_True;
}*/

View File

@@ -0,0 +1,48 @@
-- File: GeomFill_Generator.cdl
-- Created: Thu Feb 17 10:44:36 1994
-- Author: Bruno DUMORTIER
-- <dub@fuegox>
---Copyright: Matra Datavision 1994
class Generator from GeomFill inherits Profiler from GeomFill
---Purpose: Create a surface using generating lines. Inherits
-- profiler. The surface will be a BSplineSurface
-- passing by all the curves described in the
-- generator. The VDegree of the resulting surface is
-- 1.
uses
Surface from Geom
raises
NotDone from StdFail,
DomainError from Standard
is
Create returns Generator from GeomFill;
Perform(me : in out ;
PTol : in Real from Standard)
---Purpose: Converts all curves to BSplineCurves.
-- Set them to the common profile.
-- Compute the surface (degv = 1).
-- <PTol> is used to compare 2 knots.
is redefined;
Surface(me)
returns Surface from Geom
---C++: return const&
---C++: inline
is static;
fields
mySurface : Surface from Geom;
end Generator;

View File

@@ -0,0 +1,76 @@
// File: GeomFill_Generator.cxx
// Created: Fri Feb 25 09:10:38 1994
// Author: Bruno DUMORTIER
// <dub@fuegox>
#include <GeomFill_Generator.ixx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColgp_Array2OfPnt.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array2OfReal.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_BSplineSurface.hxx>
//=======================================================================
//function : GeomFill_Generator
//purpose :
//=======================================================================
GeomFill_Generator::GeomFill_Generator()
{
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void GeomFill_Generator::Perform(const Standard_Real PTol)
{
// Perform the profile of the sections.
GeomFill_Profiler::Perform( PTol);
// Create the surface.
Standard_Integer i,j;
Standard_Integer NbUPoles = NbPoles();
Standard_Integer NbVPoles = mySequence.Length();
Standard_Integer NbUKnots = NbKnots();
Standard_Integer NbVKnots = NbVPoles;
Standard_Boolean isUPeriodic = IsPeriodic();
Standard_Boolean isVPeriodic = Standard_False;
TColgp_Array2OfPnt Poles ( 1, NbUPoles, 1, NbVPoles);
TColStd_Array2OfReal Weights( 1, NbUPoles, 1, NbVPoles);
TColStd_Array1OfReal UKnots ( 1, NbUKnots);
TColStd_Array1OfReal VKnots ( 1, NbVKnots);
TColStd_Array1OfInteger UMults ( 1, NbUKnots);
TColStd_Array1OfInteger VMults ( 1, NbVKnots);
VMults.Init(1);
VMults(1) = VMults(NbVKnots) = 2;
KnotsAndMults( UKnots, UMults);
TColgp_Array1OfPnt Pole ( 1, NbUPoles);
TColStd_Array1OfReal Weight( 1, NbUPoles);
for ( j = 1; j <= NbVPoles; j++) {
Handle(Geom_BSplineCurve) Cj =
Handle(Geom_BSplineCurve)::DownCast(mySequence(j));
Cj->Poles(Pole);
Cj->Weights(Weight);
VKnots(j) = (Standard_Real)(j-1);
for ( i = 1; i <= NbUPoles; i++) {
Poles(i,j) = Pole (i);
Weights(i,j) = Weight(i);
}
}
mySurface = new Geom_BSplineSurface( Poles, Weights, UKnots, VKnots,
UMults, VMults, Degree(), 1,
isUPeriodic, isVPeriodic);
}

View File

@@ -0,0 +1,11 @@
// File: GeomFill_Generator.lxx
// Created: Fri Feb 25 09:15:58 1994
// Author: Bruno DUMORTIER
// <dub@fuegox>
inline const Handle(Geom_Surface)& GeomFill_Generator::Surface() const
{
return mySurface;
}

View File

@@ -0,0 +1,140 @@
-- File: GeomFill_GuideTrihedronAC.cdl
-- Created: Tue Jun 23 15:36:58 1998
-- Author: Stephanie HUMEAU
-- <shu@sun17>
---Copyright: Matra Datavision 1998
class GuideTrihedronAC from GeomFill
inherits TrihedronWithGuide from GeomFill
---Purpose: Trihedron in the case of a sweeping along a guide curve.
-- defined by curviline absciss
uses
Shape from GeomAbs,
Array1OfReal from TColStd,
Vec from gp,
Curve from Geom,
HCurve from Adaptor3d,
TrihedronLaw from GeomFill,
CurvlinFunc from Approx
raises
OutOfRange, ConstructionError
is
Create(guide : HCurve from Adaptor3d)
returns GuideTrihedronAC from GeomFill;
SetCurve(me:mutable; C : HCurve from Adaptor3d)
is redefined;
Copy(me) returns TrihedronLaw from GeomFill
is redefined;
Guide(me)
returns HCurve from Adaptor3d
is redefined;
D0( me : mutable;
Param : Real;
Tangent : out Vec from gp;
Normal : out Vec from gp;
BiNormal : out Vec from gp)
returns Boolean is redefined;
D1( me : mutable;
Param : Real;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp)
returns Boolean is redefined;
D2( me : mutable;
Param : Real;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
D2Tangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
D2Normal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp;
D2BiNormal : out Vec from gp)
returns Boolean is redefined;
--
-- =================== Management of continuity ===================
--
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>.
-- May be one if Continuity(me) >= <S>
returns Integer is redefined;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is redefined;
SetInterval(me: mutable; First, Last: Real from Standard)
---Purpose: Sets the bounds of the parametric interval on
-- the function
-- This determines the derivatives in these values if the
-- function is not Cn.
is redefined;
-- =================== To help computation of Tolerance ===============
GetAverageLaw(me : mutable;
ATangent : out Vec from gp;
ANormal : out Vec from gp;
ABiNormal : out Vec from gp)
---Purpose: Get average value of M(t) and V(t) it is usfull to
-- make fast approximation of rational surfaces.
is redefined;
-- =================== To help Particular case ===============
IsConstant(me)
---Purpose: Say if the law is Constant
-- Return False by Default.
returns Boolean
is redefined;
IsOnlyBy3dCurve(me)
---Purpose: Say if the law is defined, only by the 3d Geometry of
-- the setted Curve
-- Return False by Default.
returns Boolean
is redefined;
Origine(me : mutable;
OrACR1 : Real;
OrACR2 : Real)
is redefined;
fields
myGuideAC : CurvlinFunc from Approx;
Lguide : Real from Standard;
myCurveAC : CurvlinFunc from Approx;
L : Real from Standard;
myCurve : HCurve from Adaptor3d;
UTol, STol : Real;
Orig1 : Real from Standard;
Orig2 : Real from Standard;
end GuideTrihedronAC;

View File

@@ -0,0 +1,425 @@
// File: GeomFill_GuideTrihedronAC.cxx
// Creted: Tue Jun 23 15:39:24 1998
// Author: Stephanie HUMEAU
// <shu@sun17>
#include <GeomFill_GuideTrihedronAC.ixx>
#include <gp_Pnt.hxx>
#include <gp_Dir.hxx>
#include <gp_Vec.hxx>
#include <Precision.hxx>
#include <TColStd_SequenceOfReal.hxx>
#include <Approx_CurvlinFunc.hxx>
#include <Adaptor3d_Curve.hxx>
#include <GeomAdaptor.hxx>
#include <GeomAdaptor_HCurve.hxx>
#include <GeomFill_Frenet.hxx>
#include <GeomLib.hxx>
//=======================================================================
//function : GuideTrihedron
//purpose : Constructor
//=======================================================================
GeomFill_GuideTrihedronAC::GeomFill_GuideTrihedronAC(const Handle(Adaptor3d_HCurve) & guide)
{
myCurve.Nullify();
myGuide = guide;
myTrimG = guide;
myGuideAC = new (Approx_CurvlinFunc) (myGuide,1.e-7);
Lguide = myGuideAC->GetLength();
UTol = STol = Precision::PConfusion();
Orig1 = 0; // origines pour le cas path multi-edges
Orig2 = 1;
}
//=======================================================================
//function : Guide
//purpose : calculation of trihedron
//=======================================================================
Handle(Adaptor3d_HCurve) GeomFill_GuideTrihedronAC::Guide()const
{
return myGuide;
}
//=======================================================================
//function : D0
//purpose : calculation of trihedron
//=======================================================================
Standard_Boolean GeomFill_GuideTrihedronAC::D0(const Standard_Real Param,
gp_Vec& Tangent,
gp_Vec& Normal,
gp_Vec& BiNormal)
{
Standard_Real s = myCurveAC->GetSParameter(Param); // abscisse curviligne <=> Param
Standard_Real OrigG = Orig1 + s*(Orig2-Orig1); // abscisse curv sur le guide (cas multi-edges)
Standard_Real tG = myGuideAC->GetUParameter(myGuide->GetCurve(), OrigG, 1); // param <=> s sur theGuide
gp_Pnt P, PG;
gp_Vec To, B;
myTrimmed->D1(Param, P, To);//point et derivee au parametre Param sur myCurve
myTrimG->D0(tG, PG);// point au parametre tG sur myGuide
gp_Vec n (P, PG); // vecteur definissant la normale
Normal = n.Normalized();
B = To.Crossed(Normal);
BiNormal = B/B.Magnitude();
Tangent = Normal.Crossed(BiNormal);
Tangent.Normalize();
return Standard_True;
}
//=======================================================================
//function : D1
//purpose : calculation of trihedron and first derivative
//=======================================================================
Standard_Boolean GeomFill_GuideTrihedronAC::D1(const Standard_Real Param,
gp_Vec& Tangent,
gp_Vec& DTangent,
gp_Vec& Normal,
gp_Vec& DNormal,
gp_Vec& BiNormal,
gp_Vec& DBiNormal)
{
//triedre
Standard_Real s, OrigG, tG, dtg;
// abscisse curviligne <=> Param
s = myCurveAC->GetSParameter(Param);
// parametre <=> s sur theGuide
OrigG = Orig1 + s*(Orig2-Orig1);
// parametre <=> s sur theGuide
tG = myGuideAC->GetUParameter(myGuide->GetCurve(), OrigG, 1);
gp_Pnt P, PG;
gp_Vec To, DTo, TG, B, BPrim;
myTrimmed->D2(Param, P, To, DTo);
myTrimG->D1(tG, PG, TG);
gp_Vec n (P, PG), dn;
Standard_Real Norm = n.Magnitude();
if (Norm < 1.e-12) {
Norm = 1;
#if DEB
cout << "GuideTrihedronAC : Normal indefinie" << endl;
#endif
}
n /= Norm;
//derivee de n par rapport a Param
dtg = (Orig2-Orig1)*(To.Magnitude()/TG.Magnitude())*(Lguide/L);
dn.SetLinearForm(dtg, TG, -1, To);
dn /= Norm;
// triedre
Normal = n;
B = To.Crossed(Normal);
Standard_Real NormB = B.Magnitude();
B/= NormB;
BiNormal = B;
Tangent = Normal.Crossed(BiNormal);
Tangent.Normalize();
// derivee premiere
DNormal.SetLinearForm(-(n.Dot(dn)), n, dn);
BPrim.SetLinearForm(DTo.Crossed(Normal), To.Crossed(DNormal));
DBiNormal.SetLinearForm(-(B.Dot(BPrim)), B, BPrim);
DBiNormal /= NormB;
DTangent.SetLinearForm(Normal.Crossed(DBiNormal), DNormal.Crossed(BiNormal));
return Standard_True;
}
//=======================================================================
//function : D2
//purpose : calculation of trihedron and derivatives
//=======================================================================
Standard_Boolean GeomFill_GuideTrihedronAC::D2(const Standard_Real Param,
gp_Vec& Tangent,
gp_Vec& DTangent,
gp_Vec& D2Tangent,
gp_Vec& Normal,
gp_Vec& DNormal,
gp_Vec& D2Normal,
gp_Vec& BiNormal,
gp_Vec& DBiNormal,
gp_Vec& D2BiNormal)
{
// abscisse curviligne <=> Param
Standard_Real s = myCurveAC->GetSParameter(Param);
// parametre <=> s sur theGuide
Standard_Real OrigG = Orig1 + s*(Orig2-Orig1);
Standard_Real tG = myGuideAC->GetUParameter(myGuide->GetCurve(),
OrigG, 1);
gp_Pnt P,PG;
gp_Vec TG,DTG;
// gp_Vec To,DTo,D2To,B;
gp_Vec To,DTo,D2To;
myTrimmed->D3(Param, P, To, DTo, D2To);
myTrimG->D2(tG, PG, TG, DTG);
Standard_Real NTo = To.Magnitude();
Standard_Real N2To = To.SquareMagnitude();
Standard_Real NTG = TG.Magnitude();
Standard_Real N2Tp = TG.SquareMagnitude();
Standard_Real d2tp_dt2, dtg_dt;
dtg_dt = (Orig2-Orig1)*(NTo/NTG)*(Lguide/L);
gp_Vec n(P, PG); // vecteur definissant la normale
Standard_Real Norm = n.Magnitude(), ndn;
#ifdef DEB
Standard_Real Norm2 = n.SquareMagnitude();
#else
n.SquareMagnitude();
#endif
//derivee de n par rapport a Param
gp_Vec dn, d2n;
dn.SetLinearForm(dtg_dt, TG, -1, To);
//derivee seconde de tG par rapport a Param
d2tp_dt2 = (Orig2-Orig1)*(Lguide/L) *
( DTo.Dot(To) / (NTo*NTG) - N2To*TG*DTG*(Lguide/L) / (N2Tp*N2Tp));
//derivee seconde de n par rapport a Param
d2n.SetLinearForm(dtg_dt*dtg_dt,DTG, d2tp_dt2, TG, -1, DTo);
if (Norm > 1.e-9) {
n /= Norm;
dn /= Norm;
d2n /= Norm;
}
//triedre
Normal = n;
gp_Vec TN, DTN, D2TN;
TN = To.Crossed(Normal);
Standard_Real Norma = TN.Magnitude();
if (Norma > 1.e-9) TN /= Norma;
BiNormal = TN;
Tangent = Normal.Crossed(BiNormal);
// Tangent.Normalize();
// derivee premiere du triedre
// gp_Vec DTN = DTo.Crossed(Normal);
// gp_Vec TDN = To.Crossed(DNormal);
// gp_Vec DT = DTN + TDN;
ndn = n.Dot(dn);
DNormal.SetLinearForm(-ndn, n, dn);
DTN.SetLinearForm(DTo.Crossed(Normal), To.Crossed(DNormal));
DTN /= Norma;
Standard_Real TNDTN = TN.Dot(DTN);
DBiNormal.SetLinearForm(-TNDTN, TN, DTN);
DTangent.SetLinearForm(Normal.Crossed(DBiNormal),
DNormal.Crossed(BiNormal));
//derivee seconde du triedre
#ifdef DEB
gp_Vec DTDN = DTo.Crossed(DNormal);
#else
DTo.Crossed(DNormal);
#endif
Standard_Real TN2 = TN.SquareMagnitude();
D2Normal.SetLinearForm(-2*ndn, dn,
3*ndn*ndn - (dn.SquareMagnitude() + n.Dot(d2n)),n,
d2n);
D2TN.SetLinearForm(1, D2To.Crossed(Normal),
2, DTo.Crossed(DNormal),
To.Crossed(D2Normal));
D2TN /= Norma;
D2BiNormal.SetLinearForm(-2*TNDTN, DTN,
3*TNDTN*TNDTN - (TN2 + TN.Dot(D2TN)), TN,
D2TN);
D2Tangent.SetLinearForm(1, D2Normal.Crossed(BiNormal),
2, DNormal.Crossed(DBiNormal),
Normal.Crossed(D2BiNormal) );
// return Standard_True;
return Standard_False;
}
//=======================================================================
//function : Copy
//purpose :
//=======================================================================
Handle(GeomFill_TrihedronLaw) GeomFill_GuideTrihedronAC::Copy() const
{
Handle(GeomFill_GuideTrihedronAC) copy =
new (GeomFill_GuideTrihedronAC) (myGuide);
copy->SetCurve(myCurve);
copy->Origine(Orig1,Orig2);
return copy;
}
//=======================================================================
//function : SetCurve
//purpose :
//=======================================================================
void GeomFill_GuideTrihedronAC::SetCurve(const Handle(Adaptor3d_HCurve)& C)
{
myCurve = C;
myTrimmed = C;
if (!myCurve.IsNull()) {
myCurveAC = new (Approx_CurvlinFunc) (C,1.e-7);
L = myCurveAC->GetLength();
// CorrectOrient(myGuide);
}
}
//=======================================================================
//function : NbIntervals
//purpose :
//=======================================================================
Standard_Integer GeomFill_GuideTrihedronAC::NbIntervals(const GeomAbs_Shape S) const
{
Standard_Integer Nb;
Nb = myCurveAC->NbIntervals(S);
TColStd_Array1OfReal DiscC(1, Nb+1);
myCurveAC->Intervals(DiscC, S);
Nb = myGuideAC->NbIntervals(S);
TColStd_Array1OfReal DiscG(1, Nb+1);
myGuideAC->Intervals(DiscG, S);
TColStd_SequenceOfReal Seq;
GeomLib::FuseIntervals(DiscC, DiscG, Seq);
return Seq.Length()-1;
}
//======================================================================
//function :Intervals
//purpose :
//=======================================================================
void GeomFill_GuideTrihedronAC::Intervals(TColStd_Array1OfReal& TT,
const GeomAbs_Shape S) const
{
Standard_Integer Nb, ii;
Nb = myCurveAC->NbIntervals(S);
TColStd_Array1OfReal DiscC(1, Nb+1);
myCurveAC->Intervals(DiscC, S);
Nb = myGuideAC->NbIntervals(S);
TColStd_Array1OfReal DiscG(1, Nb+1);
myGuideAC->Intervals(DiscG, S);
TColStd_SequenceOfReal Seq;
GeomLib::FuseIntervals(DiscC, DiscG, Seq);
Nb = Seq.Length();
for (ii=1; ii<=Nb; ii++) {
TT(ii) = myCurveAC->GetUParameter(myCurve->GetCurve(), Seq(ii), 1);
}
}
//======================================================================
//function :SetInterval
//purpose :
//=======================================================================
void GeomFill_GuideTrihedronAC::SetInterval(const Standard_Real First,
const Standard_Real Last)
{
myTrimmed = myCurve->Trim(First, Last, UTol);
Standard_Real Sf, Sl, U;
Sf = myCurveAC->GetSParameter(First);
Sl = myCurveAC->GetSParameter(Last);
// if (Sl>1) Sl=1;
// myCurveAC->Trim(Sf, Sl, UTol);
U = Orig1 + Sf*(Orig2-Orig1);
Sf = myGuideAC->GetUParameter(myGuide->GetCurve(), U, 1);
U = Orig1 + Sl*(Orig2-Orig1);
Sl = myGuideAC->GetUParameter(myGuide->GetCurve(), U, 1);
myTrimG = myGuide->Trim(Sf, Sl, UTol);
}
//=======================================================================
//function : GetAverageLaw
//purpose :
//=======================================================================
void GeomFill_GuideTrihedronAC::GetAverageLaw(gp_Vec& ATangent,
gp_Vec& ANormal,
gp_Vec& ABiNormal)
{
Standard_Integer ii;
Standard_Real t, Delta = (myCurve->LastParameter() -
myCurve->FirstParameter())/20.001;
ATangent.SetCoord(0.,0.,0.);
ANormal.SetCoord(0.,0.,0.);
ABiNormal.SetCoord(0.,0.,0.);
gp_Vec T, N, B;
for (ii=1, T; ii<=20; ii++) {
t = myCurve->FirstParameter() +(ii-1)*Delta;
D0(t, T, N, B);
ATangent +=T;
ANormal +=N;
ABiNormal+=B;
}
ATangent /= 20;
ANormal /= 20;
ABiNormal /= 20;
}
//=======================================================================
//function : IsConstant
//purpose :
//=======================================================================
Standard_Boolean GeomFill_GuideTrihedronAC::IsConstant() const
{
return Standard_False;
}
//=======================================================================
//function : IsOnlyBy3dCurve
//purpose :
//=======================================================================
Standard_Boolean GeomFill_GuideTrihedronAC::IsOnlyBy3dCurve() const
{
return Standard_False;
}
//=======================================================================
//function : Origine
//purpose :
//=======================================================================
void GeomFill_GuideTrihedronAC::Origine(const Standard_Real OrACR1,
const Standard_Real OrACR2)
{
Orig1 = OrACR1;
Orig2 = OrACR2;
}

View File

@@ -0,0 +1,159 @@
-- File: GeomFill_GuideTrihedronPlan.cdl
-- Created: Tue Jun 23 15:36:58 1998
-- Author: Stephanie HUMEAU
-- <shu@sun17>
---Copyright: Matra Datavision 1998
class GuideTrihedronPlan from GeomFill
---Purpose: Trihedron in the case of sweeping along a guide curve defined
-- by the orthogonal plan on the trajectory
inherits TrihedronWithGuide from GeomFill
uses
Shape from GeomAbs,
Array1OfReal from TColStd,
HArray2OfPnt2d from TColgp,
Vec from gp,
Curve from Geom,
HCurve from Adaptor3d,
TrihedronLaw from GeomFill,
Frenet from GeomFill,
PipeError from GeomFill,
Vector from math
raises
OutOfRange, ConstructionError
is
Create (theGuide : HCurve from Adaptor3d)
returns GuideTrihedronPlan from GeomFill;
Init (me : mutable)
is static private;
SetCurve(me:mutable;
thePath : HCurve from Adaptor3d)
is redefined;
Copy(me) returns TrihedronLaw from GeomFill
is redefined;
ErrorStatus(me)
---Purpose:Give a status to the Law
-- Returns PipeOk (default implementation)
returns PipeError from GeomFill
is redefined;
Guide(me)
returns HCurve from Adaptor3d
is redefined;
D0( me : mutable;
Param : Real;
Tangent : out Vec from gp;
Normal : out Vec from gp;
BiNormal : out Vec from gp)
returns Boolean is redefined;
D1( me : mutable;
Param : Real;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp)
returns Boolean is redefined;
D2( me : mutable;
Param : Real;
Tangent : out Vec from gp;
DTangent : out Vec from gp;
D2Tangent : out Vec from gp;
Normal : out Vec from gp;
DNormal : out Vec from gp;
D2Normal : out Vec from gp;
BiNormal : out Vec from gp;
DBiNormal : out Vec from gp;
D2BiNormal : out Vec from gp)
returns Boolean is redefined;
--
-- =================== Management of continuity ===================
--
SetInterval(me: mutable; First, Last: Real from Standard)
---Purpose: Sets the bounds of the parametric interval on
-- the function
-- This determines the derivatives in these values if the
-- function is not Cn.
is redefined;
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>.
-- May be one if Continuity(me) >= <S>
returns Integer is redefined;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is redefined;
-- =================== To help computation of Tolerance ===============
GetAverageLaw(me : mutable;
ATangent : out Vec from gp;
ANormal : out Vec from gp;
ABiNormal : out Vec from gp)
---Purpose: Get average value of M(t) and V(t) it is usfull to
-- make fast approximation of rational surfaces.
is redefined;
-- =================== To help Particular case ===============
IsConstant(me)
---Purpose: Say if the law is Constant
-- Return False by Default.
returns Boolean
is redefined;
IsOnlyBy3dCurve(me)
---Purpose: Say if the law is defined, only by the 3d Geometry of
-- the setted Curve
-- Return False by Default.
returns Boolean
is redefined;
Origine(me : mutable;
OrACR1 : Real;
OrACR2 : Real)
is redefined;
InitX(me : mutable;
Param : Real from Standard)
is private;
fields
myTrimmed : HCurve from Adaptor3d;
myCurve : HCurve from Adaptor3d;
Pole : HArray2OfPnt2d from TColgp;
X, XTol : Vector from math;
Inf, Sup : Vector from math;
frenet : Frenet from GeomFill;
myNbPts : Integer from Standard;
myStatus : PipeError from GeomFill;
end GuideTrihedronPlan;

View File

@@ -0,0 +1,640 @@
// File: GeomFill_GuideTrihedronPlan.cxx
// Created: Thu Jul 02 15:39:24 1998
// Author: Stephanie HUMEAU
// <shu@sun17>
#include <GeomFill_GuideTrihedronPlan.ixx>
#include <gp_Pnt.hxx>
#include <gp_Pnt2d.hxx>
//#include <gp_Trsf2d.hxx>
//#include <Bnd_Box2d.hxx>
#include <ElCLib.hxx>
#include <Adaptor3d_Curve.hxx>
#include <GeomAdaptor_HCurve.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <Geom_Plane.hxx>
#include <IntCurveSurface_IntersectionPoint.hxx>
#include <IntCurveSurface_HInter.hxx>
#include <GeomFill_Frenet.hxx>
#include <GeomFill_PlanFunc.hxx>
#include <math_Vector.hxx>
#include <math_FunctionRoot.hxx>
#include <math_Matrix.hxx>
#include <Precision.hxx>
#if DRAW
#include <DrawTrSurf.hxx>
#endif
#if DEB
static void TracePlan(const Handle(Geom_Surface)& Plan)
{
cout << "Pas d'intersection Guide/Plan" << endl;
#if DRAW
char* Temp = "ThePlan" ;
DrawTrSurf::Set(Temp, Plan);
// DrawTrSurf::Set("ThePlan", Plan);
#endif
}
#endif
//==================================================================
//Function: InGoodPeriod
//Purpose : Recadre un paramtere
//==================================================================
static void InGoodPeriod(const Standard_Real Prec,
const Standard_Real Period,
Standard_Real& Current)
{
Standard_Real Diff=Current-Prec;
Standard_Integer nb = (Standard_Integer ) IntegerPart(Diff/Period);
Current -= nb*Period;
Diff = Current-Prec;
if (Diff > Period/2) Current -= Period;
else if (Diff < -Period/2) Current += Period;
}
//=======================================================================
//function : GuideTrihedronPlan
//purpose : Constructor
//=======================================================================
GeomFill_GuideTrihedronPlan::GeomFill_GuideTrihedronPlan (const Handle(Adaptor3d_HCurve)& theGuide) :
X(1,1),
XTol(1,1),
Inf(1,1), Sup(1,1),
myStatus(GeomFill_PipeOk)
{
myCurve.Nullify();
myGuide = theGuide; // guide
myTrimG = theGuide;
myNbPts = 20; // nb points pour calculs
Pole = new (TColgp_HArray2OfPnt2d)(1,1,1,myNbPts);//tab pr stocker Pprime (pt sur guide)
frenet = new (GeomFill_Frenet)();
XTol.Init(1.e-6);
XTol(1) = myGuide->Resolution(1.e-6);
}
//=======================================================================
//function : Init
//purpose : calcule myNbPts points sur la courbe guide (<=> normale)
//=======================================================================
void GeomFill_GuideTrihedronPlan::Init()
{
myStatus = GeomFill_PipeOk;
gp_Pnt P;
// Bnd_Box2d Box;
// Box.Update(-0.1, -0.1, 0.1, 0.1); // Taille minimal
gp_Vec Tangent,Normal,BiNormal;
Standard_Integer ii;
Standard_Real t, DeltaG, w;
Standard_Real f = myCurve->FirstParameter();
Standard_Real l = myCurve->LastParameter();
Handle(Geom_Plane) Plan;
Handle(GeomAdaptor_HSurface) Pl;
IntCurveSurface_IntersectionPoint PInt;
IntCurveSurface_HInter Int;
frenet->SetCurve(myCurve);
DeltaG = (myGuide->LastParameter() - myGuide->FirstParameter())/2;
Inf(1) = myGuide->FirstParameter() - DeltaG;
Sup(1) = myGuide->LastParameter() + DeltaG;
if (!myGuide->IsPeriodic()) {
myTrimG = myGuide->Trim(myGuide->FirstParameter()- DeltaG/100,
myGuide->LastParameter() + DeltaG/100,
DeltaG*1.e-7);
}
else {
myTrimG = myGuide;
}
// Standard_Real Step = DeltaG/100;
DeltaG /= 3;
for (ii=1; ii<=myNbPts; ii++)
{
t = Standard_Real(myNbPts - ii)*f + Standard_Real(ii - 1)*l;
t /= (myNbPts-1);
myCurve->D0(t, P);
frenet->D0(t, Tangent, Normal, BiNormal);
Plan = new (Geom_Plane) (P, Tangent);
Pl = new(GeomAdaptor_HSurface) (Plan);
Int.Perform(myTrimG, Pl); // intersection plan / guide
if (Int.NbPoints() == 0) {
#if DEB
TracePlan(Plan);
#endif
w = (fabs(myGuide->LastParameter() -w) > fabs(myGuide->FirstParameter()-w) ? myGuide->FirstParameter() : myGuide->LastParameter());
myStatus = GeomFill_PlaneNotIntersectGuide;
//return;
}
else
{
gp_Pnt Pmin;
PInt = Int.Point(1);
Pmin = PInt.Pnt();
Standard_Real Dmin = P.Distance(Pmin);
for (Standard_Integer jj=2;jj<=Int.NbPoints();jj++)
{
Pmin = Int.Point(jj).Pnt();
if (P.Distance(Pmin) < Dmin)
{
PInt = Int.Point(jj);
Dmin = P.Distance(Pmin);
}
}//for_jj
w = PInt.W();
}
if (ii>1) {
Standard_Real Diff = w - Pole->Value(1, ii-1).Y();
if (Abs(Diff) > DeltaG) {
if (myGuide->IsPeriodic()) {
InGoodPeriod (Pole->Value(1, ii-1).Y(),
myGuide->Period(), w);
Diff = w - Pole->Value(1, ii-1).Y();
}
}
#if DEB
if (Abs(Diff) > DeltaG) {
cout << "Trihedron Plan Diff on Guide : " <<
Diff << endl;
}
#endif
}
gp_Pnt2d p1(t, w); // on stocke les parametres
Pole->SetValue(1, ii, p1);
}// for_ii
}
//=======================================================================
//function : SetCurve
//purpose : calculation of trihedron
//=======================================================================
void GeomFill_GuideTrihedronPlan::SetCurve(const Handle(Adaptor3d_HCurve)& C)
{
myCurve = C;
if (!myCurve.IsNull()) Init();
}
//=======================================================================
//function : Guide
//purpose : calculation of trihedron
//=======================================================================
Handle(Adaptor3d_HCurve) GeomFill_GuideTrihedronPlan::Guide()const
{
return myGuide;
}
//=======================================================================
//function : D0
//purpose : calculation of trihedron
//=======================================================================
Standard_Boolean GeomFill_GuideTrihedronPlan::D0(const Standard_Real Param,
gp_Vec& Tangent,
gp_Vec& Normal,
gp_Vec& BiNormal)
{
gp_Pnt P, Pprime;
// gp_Vec To;
myCurve->D0(Param, P);
frenet->D0(Param,Tangent,Normal,BiNormal);
//initialisation de la recherche
InitX(Param);
Standard_Integer Iter = 50;
// fonction dont il faut trouver la racine : G(W)-Pl(U,V)=0
GeomFill_PlanFunc E(P, Tangent, myGuide);
// resolution
math_FunctionRoot Result(E, X(1), XTol(1),
Inf(1), Sup(1), Iter);
if (Result.IsDone())
{
Standard_Real Res = Result.Root();
// R = Result.Root(); // solution
Pprime = myTrimG->Value(Res); // pt sur courbe guide
gp_Vec n (P, Pprime); // vecteur definissant la normale du triedre
Normal = n.Normalized();
BiNormal = Tangent.Crossed(Normal);
BiNormal.Normalized();
}
else { // Erreur...
#if DEB
cout << "D0 :";
// plan ortho a la trajectoire pour determiner Pprime
Handle(Geom_Plane) Plan = new (Geom_Plane)(P, Tangent);
TracePlan(Plan);
#endif
myStatus = GeomFill_PlaneNotIntersectGuide;
return Standard_False;
}
return Standard_True;
}
//=======================================================================
//function : D1
//purpose : calculation of trihedron and first derivative
//=======================================================================
Standard_Boolean GeomFill_GuideTrihedronPlan::D1(const Standard_Real Param,
gp_Vec& Tangent,
gp_Vec& DTangent,
gp_Vec& Normal,
gp_Vec& DNormal,
gp_Vec& BiNormal,
gp_Vec& DBiNormal)
{
// return Standard_False;
gp_Pnt P, PG;
gp_Vec To,TG;
// triedre de frenet sur la trajectoire
myCurve->D1(Param, P, To);
frenet->D1(Param,Tangent,DTangent,Normal,DNormal,BiNormal,DBiNormal);
// tolerance sur E
Standard_Integer Iter = 50;
// fonction dont il faut trouver la racine : G(W)-Pl(U,V)=0
InitX(Param);
GeomFill_PlanFunc E(P, Tangent, myGuide);
// resolution
math_FunctionRoot Result(E, X(1), XTol(1),
Inf(1), Sup(1), Iter);
if (Result.IsDone())
{
Standard_Real Res = Result.Root();
// R = Result.Root(); // solution
myTrimG->D1(Res, PG, TG);
gp_Vec n (P, PG), dn; // vecteur definissant la normale du triedre
Standard_Real Norm = n.Magnitude();
if (Norm < 1.e-12) {
Norm = 1.0;
}
n /=Norm;
Normal = n;
BiNormal = Tangent.Crossed(Normal);
// derivee premiere du triedre
Standard_Real dedx, dedt, dtg_dt;
E.Derivative(Res, dedx);
E.DEDT(Res, To, DTangent, dedt);
dtg_dt = -dedt/dedx;
/* Standard_Real h=1.e-7, e, etg, etc;
E.Value(Res, e);
E.Value(Res+h, etg);
if ( Abs( (etg-e)/h - dedx) > 1.e-4) {
cout << "err :" << (etg-e)/h - dedx << endl;
}
gp_Pnt pdbg;
gp_Vec td, nb, bnb;
myCurve->D0(Param+h, pdbg);
frenet->D0(Param+h,td, nb, bnb);
GeomFill_PlanFunc Edeb(pdbg, td, myGuide);
Edeb.Value(Res, etc);
if ( Abs( (etc-e)/h - dedt) > 1.e-4) {
cout << "err :" << (etc-e)/h - dedt << endl;
} */
dn.SetLinearForm(dtg_dt, TG, -1, To);
DNormal.SetLinearForm(-(n*dn), n, dn);
DNormal /= Norm;
DBiNormal.SetLinearForm(Tangent.Crossed(DNormal),
DTangent.Crossed(Normal));
}
else {// Erreur...
#if DEB
cout << "D1 :";
// plan ortho a la trajectoire
Handle(Geom_Plane) Plan = new (Geom_Plane)(P, Tangent);
TracePlan(Plan);
#endif
myStatus = GeomFill_PlaneNotIntersectGuide;
return Standard_False;
}
return Standard_True;
}
//=======================================================================
//function : D2
//purpose : calculation of trihedron and derivatives
//=======================================================================
Standard_Boolean GeomFill_GuideTrihedronPlan::D2(const Standard_Real Param,
gp_Vec& Tangent,
gp_Vec& DTangent,
gp_Vec& D2Tangent,
gp_Vec& Normal,
gp_Vec& DNormal,
gp_Vec& D2Normal,
gp_Vec& BiNormal,
gp_Vec& DBiNormal,
gp_Vec& D2BiNormal)
{
// gp_Pnt P, PG;
gp_Pnt P;
// gp_Vec To,DTo,TG,DTG;
gp_Vec To,DTo;
myCurve->D2(Param, P, To, DTo);
// triedre de Frenet sur la trajectoire
frenet->D2(Param,Tangent,DTangent,D2Tangent,
Normal,DNormal,D2Normal,
BiNormal,DBiNormal,D2BiNormal);
/*
// plan ortho a Tangent pour trouver la pt Pprime sur le guide
Handle(Geom_Plane) Plan = new (Geom_Plane)(P, Tangent);
Handle(GeomAdaptor_HSurface) Pl= new(GeomAdaptor_HSurface)(Plan);
Standard_Integer Iter = 50;
// fonction dont il faut trouver la racine : G(W) - Pl(U,V)=0
GeomFill_FunctionPipe E(Pl , myGuide);
InitX(Param);
// resolution
math_FunctionSetRoot Result(E, X, XTol,
Inf, Sup, Iter);
if (Result.IsDone())
{
math_Vector R(1,3);
R = Result.Root(); // solution
myTrimG->D2(R(1), PG, TG, DTG);
gp_Vec n (P, PG); // vecteur definissant la normale du triedre
Standard_Real Norm = n.Magnitude();
n /= Norm;
Normal = n.Normalized();
BiNormal = Tangent.Crossed(Normal);
// derivee premiere du triedre
Standard_Real dtp_dt;
dtp_dt = (To*Tangent - Norm*(n*DTangent))/(Tangent*TG);
gp_Vec dn, d2n;
dn.SetLinearForm(dtp_dt, TG, -1, To);
DNormal.SetLinearForm(-(n*dn), n, dn);
DNormal /= Norm;
DBiNormal = Tangent.Crossed(DNormal) + DTangent.Crossed(Normal);
// derivee seconde du triedre
Standard_Real d2tp_dt2;
d2tp_dt2 = (DTo*Tangent+To*DTangent - dn*DTangent-Norm*n*D2Tangent)/(TG*Tangent)
- (To*Tangent-Norm*n*DTangent) * (DTG*dtp_dt*Tangent+TG*DTangent)
/ ((TG*Tangent)*(TG*Tangent));
d2n.SetLinearForm(dtp_dt*dtp_dt, DTG, d2tp_dt2, TG, -DTo);
dn/=Norm;
d2n/=Norm;
D2Normal.SetLinearForm(3*Pow(n*dn,2)- (dn.SquareMagnitude() + n*d2n), n,
-2*(n*dn), dn,
d2n);
D2BiNormal.SetLinearForm(1, D2Tangent.Crossed(Normal),
2, DTangent.Crossed(DNormal),
Tangent.Crossed(D2Normal));
}
else {// Erreur...
#if DEB
cout << "D2 :";
TracePlan(Plan);
#endif
myStatus = GeomFill_PlaneNotIntersectGuide;
return Standard_False;
}
*/
// return Standard_True;
return Standard_False;
}
//=======================================================================
//function : Copy
//purpose :
//=======================================================================
Handle(GeomFill_TrihedronLaw) GeomFill_GuideTrihedronPlan::Copy() const
{
Handle(GeomFill_GuideTrihedronPlan) copy =
new (GeomFill_GuideTrihedronPlan) (myGuide);
copy->SetCurve(myCurve);
return copy;
}
//=======================================================================
//function : ErrorStatus
//purpose :
//=======================================================================
GeomFill_PipeError GeomFill_GuideTrihedronPlan::ErrorStatus() const
{
return myStatus;
}
//=======================================================================
//function : NbIntervals
//purpose : Version provisoire : Il faut tenir compte du guide
//=======================================================================
Standard_Integer GeomFill_GuideTrihedronPlan::NbIntervals(const GeomAbs_Shape S)const
{
Standard_Integer Nb;
GeomAbs_Shape tmpS;
switch (S) {
case GeomAbs_C0: tmpS = GeomAbs_C1; break;
case GeomAbs_C1: tmpS = GeomAbs_C2; break;
case GeomAbs_C2: tmpS = GeomAbs_C3; break;
default: tmpS = GeomAbs_CN;
}
Nb = myCurve->NbIntervals(tmpS);
return Nb;
}
//======================================================================
//function :Intervals
//purpose :
//=======================================================================
void GeomFill_GuideTrihedronPlan::Intervals(TColStd_Array1OfReal& TT,
const GeomAbs_Shape S) const
{
GeomAbs_Shape tmpS;
switch (S) {
case GeomAbs_C0: tmpS = GeomAbs_C1; break;
case GeomAbs_C1: tmpS = GeomAbs_C2; break;
case GeomAbs_C2: tmpS = GeomAbs_C3; break;
default: tmpS = GeomAbs_CN;
}
myCurve->Intervals(TT, tmpS);
}
//======================================================================
//function :SetInterval
//purpose :
//=======================================================================
void GeomFill_GuideTrihedronPlan::SetInterval(const Standard_Real First,
const Standard_Real Last)
{
myTrimmed = myCurve->Trim(First, Last, Precision::Confusion());
}
//=======================================================================
//function : GetAverageLaw
//purpose :
//=======================================================================
void GeomFill_GuideTrihedronPlan::GetAverageLaw(gp_Vec& ATangent,
gp_Vec& ANormal,
gp_Vec& ABiNormal)
{
Standard_Integer ii;
Standard_Real t, Delta = (myCurve->LastParameter() -
myCurve->FirstParameter())/20.001;
ATangent.SetCoord(0.,0.,0.);
ANormal.SetCoord(0.,0.,0.);
ABiNormal.SetCoord(0.,0.,0.);
gp_Vec T, N, B;
for (ii=1, T; ii<=20; ii++) {
t = myCurve->FirstParameter() +(ii-1)*Delta;
D0(t, T, N, B);
ATangent +=T;
ANormal +=N;
ABiNormal+=B;
}
ATangent /= 20;
ANormal /= 20;
ABiNormal /= 20;
}
//=======================================================================
//function : IsConstant
//purpose :
//=======================================================================
Standard_Boolean GeomFill_GuideTrihedronPlan::IsConstant() const
{
if ((myCurve->GetType() == GeomAbs_Line) &&
(myGuide->GetType() == GeomAbs_Line)) {
Standard_Real Angle;
Angle = myCurve->Line().Angle(myGuide->Line());
if ((Angle<1.e-12) || ((2*PI-Angle)<1.e-12) )
return Standard_True;
}
return Standard_False;
}
//=======================================================================
//function : IsOnlyBy3dCurve
//purpose :
//=======================================================================
Standard_Boolean GeomFill_GuideTrihedronPlan::IsOnlyBy3dCurve() const
{
return Standard_False;
}
//=======================================================================
//function : Origine
//purpose : Nothing!!
//=======================================================================
void GeomFill_GuideTrihedronPlan::Origine(const Standard_Real ,
const Standard_Real )
{
}
//==================================================================
//Function : InitX
//Purpose : recherche par interpolation d'une valeur initiale
//==================================================================
void GeomFill_GuideTrihedronPlan::InitX(const Standard_Real Param)
{
Standard_Integer Ideb = 1, Ifin = Pole->RowLength(), Idemi;
Standard_Real Valeur, t1, t2;
Valeur = Pole->Value(1, Ideb).X();
if (Param == Valeur) {
Ifin = Ideb+1;
}
Valeur = Pole->Value(1, Ifin).X();
if (Param == Valeur) {
Ideb = Ifin-1;
}
while ( Ideb+1 != Ifin) {
Idemi = (Ideb+Ifin)/2;
Valeur = Pole->Value(1, Idemi).X();
if (Valeur < Param) {
Ideb = Idemi;
}
else {
if ( Valeur > Param) { Ifin = Idemi;}
else {
Ideb = Idemi;
Ifin = Ideb+1;
}
}
}
t1 = Pole->Value(1,Ideb).X();
t2 = Pole->Value(1,Ifin).X();
Standard_Real diff = t2-t1;
if (diff > 1.e-7) {
Standard_Real b = (Param-t1) / diff,
a = (t2-Param) / diff;
X(1) = Pole->Value(1,Ideb).Coord(2) * a
+ Pole->Value(1,Ifin).Coord(2) * b; //param guide
}
else {
X(1) = (Pole->Value(1, Ideb).Coord(2) +
Pole->Value(1, Ifin).Coord(2)) / 2;
}
if (myGuide->IsPeriodic()) {
X(1) = ElCLib::InPeriod(X(1), myGuide->FirstParameter(),
myGuide->LastParameter());
}
}

38
src/GeomFill/GeomFill_Line.cdl Executable file
View File

@@ -0,0 +1,38 @@
-- File: GeomFill_Line.cdl
-- Created: Fri Feb 18 16:42:03 1994
-- Author: Bruno DUMORTIER
-- <dub@fuegox>
---Copyright: Matra Datavision 1994
class Line from GeomFill
---Purpose:
inherits TShared from MMgt
is
Create returns mutable Line from GeomFill;
Create(NbPoints : Integer from Standard)
returns mutable Line from GeomFill;
NbPoints(me)
returns Integer from Standard
---C++: inline
is static;
Point(me; Index: Integer from Standard)
returns Integer from Standard
---C++: inline
is static;
fields
myNbPoints : Integer from Standard;
end Line;

29
src/GeomFill/GeomFill_Line.cxx Executable file
View File

@@ -0,0 +1,29 @@
// File: GeomFill_Line.cxx
// Created: Fri Feb 18 16:48:13 1994
// Author: Bruno DUMORTIER
// <dub@fuegox>
#include <GeomFill_Line.ixx>
//=======================================================================
//function : GeomFill_Line
//purpose :
//=======================================================================
GeomFill_Line::GeomFill_Line()
{
myNbPoints = 0;
}
//=======================================================================
//function : GeomFill_Line
//purpose :
//=======================================================================
GeomFill_Line::GeomFill_Line(const Standard_Integer NbPoints)
: myNbPoints(NbPoints)
{
}

27
src/GeomFill/GeomFill_Line.lxx Executable file
View File

@@ -0,0 +1,27 @@
// File: GeomFill_Line.lxx
// Created: Fri Feb 18 17:03:34 1994
// Author: Bruno DUMORTIER
// <dub@fuegox>
//=======================================================================
//function : NbPoints
//purpose :
//=======================================================================
inline Standard_Integer GeomFill_Line::NbPoints() const
{
return myNbPoints;
}
//=======================================================================
//function : Point
//purpose :
//=======================================================================
inline Standard_Integer GeomFill_Line::Point(const Standard_Integer Index)
const
{
return Index;
}

View File

@@ -0,0 +1,53 @@
-- File: GeomFill_LocFunction.cdl
-- Created: Mon Feb 2 18:14:53 1998
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1998
private class LocFunction from GeomFill
---Purpose:
uses
LocationLaw from GeomFill,
Array1OfVec from TColgp,
Mat from gp
is
Create( Law : LocationLaw from GeomFill)
returns LocFunction from GeomFill;
D0(me : in out;
Param: Real;
First, Last : Real)
---Purpose: compute the section for v = param
returns Boolean;
D1(me : in out;
Param: Real;
First, Last : Real)
---Purpose: compute the first derivative in v direction of the
-- section for v = param
returns Boolean;
D2(me : in out;
Param: Real;
First, Last : Real)
---Purpose: compute the second derivative in v direction of the
-- section for v = param
returns Boolean;
DN(me : in out;
Param : Real;
First, Last : Real;
Order : Integer;
Result : in out Real;
Ier : out Integer);
fields
myLaw : LocationLaw from GeomFill;
V, DV, D2V : Array1OfVec from TColgp;
M, DM, D2M : Mat from gp;
end LocFunction;

View File

@@ -0,0 +1,132 @@
// File: GeomFill_LocFunction.cxx
// Created: Mon Feb 2 18:19:56 1998
// Author: Philippe MANGIN
// <pmn@sgi29>
#include <GeomFill_LocFunction.ixx>
#include <gp_Mat.hxx>
#include <gp_Vec.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TColgp_Array1OfVec2d.hxx>
GeomFill_LocFunction::GeomFill_LocFunction(const Handle(GeomFill_LocationLaw)& Law)
:V(1,4), DV(1,4), D2V(1,4)
{
myLaw = Law;
}
Standard_Boolean GeomFill_LocFunction::D0(const Standard_Real Param,
// const Standard_Real First,
const Standard_Real ,
// const Standard_Real Last)
const Standard_Real )
{
gp_Mat M;
Standard_Boolean B;
B = myLaw->D0(Param, M, V.ChangeValue(1));
V(2).SetXYZ(M.Column(1));
V(3).SetXYZ(M.Column(2));
V(4).SetXYZ(M.Column(3));
return B;
}
Standard_Boolean GeomFill_LocFunction::D1(const Standard_Real Param,
// const Standard_Real First,
const Standard_Real ,
// const Standard_Real Last)
const Standard_Real )
{
TColgp_Array1OfPnt2d T1(1,1);
TColgp_Array1OfVec2d T2(1,1);
gp_Mat M, DM;
Standard_Boolean B;
B = myLaw->D1(Param, M, V.ChangeValue(1),
DM, DV.ChangeValue(1),
T1, T2);
V(2).SetXYZ(M.Column(1));
V(3).SetXYZ(M.Column(2));
V(4).SetXYZ(M.Column(3));
DV(2).SetXYZ(DM.Column(1));
DV(3).SetXYZ(DM.Column(2));
DV(4).SetXYZ(DM.Column(3));
return B;
}
Standard_Boolean GeomFill_LocFunction::D2(const Standard_Real Param,
// const Standard_Real First,
const Standard_Real ,
// const Standard_Real Last)
const Standard_Real )
{
TColgp_Array1OfPnt2d T1(1,1);
TColgp_Array1OfVec2d T2(1,1), T3(1,1);
gp_Mat M, DM, D2M;
Standard_Boolean B;
B = myLaw->D2(Param, M, V.ChangeValue(1),
DM, DV.ChangeValue(1),
D2M, D2V.ChangeValue(1),
T1, T2, T3);
V(2).SetXYZ(M.Column(1));
V(3).SetXYZ(M.Column(2));
V(4).SetXYZ(M.Column(3));
DV(2).SetXYZ(DM.Column(1));
DV(3).SetXYZ(DM.Column(2));
DV(4).SetXYZ(DM.Column(3));
D2V(2).SetXYZ(D2M.Column(1));
D2V(3).SetXYZ(D2M.Column(2));
D2V(4).SetXYZ(D2M.Column(3));
return B;
}
void GeomFill_LocFunction::DN(const Standard_Real Param,
const Standard_Real First,
const Standard_Real Last,
const Standard_Integer Order,
Standard_Real& Result,
Standard_Integer& Ier)
{
Standard_Boolean B;
Standard_Real * AddrResult = &Result;
const Standard_Real * LocalResult=NULL;
Ier = 0;
switch (Order) {
case 0:
{
B = D0(Param, First, Last);
LocalResult = (Standard_Real*)(&V(1));
break;
}
case 1:
{
B = D1(Param, First, Last);
LocalResult = (Standard_Real*)(&DV(1));
break;
}
case 2:
{
B = D2(Param, First, Last);
LocalResult = (Standard_Real*)(&D2V(1));
break;
}
default :
{
B = Standard_False;
}
}
if (!B) {
Ier = Order+1;
}
for (Standard_Integer ii=0; ii<=11; ii++) {
AddrResult[ii] = LocalResult[ii];
}
}

View File

@@ -0,0 +1,246 @@
-- File: GeomFill_LocationDraft.cdl
-- Created: Tue Apr 21 17:05:54 1998
-- Author: Stephanie HUMEAU
-- <shu@sun17>
---Copyright: Matra Datavision 1998
class LocationDraft from GeomFill
inherits LocationLaw from GeomFill
uses
HCurve from Adaptor3d,
HSurface from Adaptor3d,
Mat from gp,
Vec from gp,
Pnt from gp,
Dir from gp,
Shape from GeomAbs,
Array1OfReal from TColStd,
Array1OfVec2d from TColgp,
Array1OfPnt2d from TColgp,
HArray1OfPnt2d from TColgp,
DraftTrihedron from GeomFill,
Curve from Geom,
Line from Geom,
TrimmedCurve from Geom
raises
NotImplemented, OutOfRange
is
Create (Direction : Dir from gp;
Angle : Real from Standard)
returns LocationDraft from GeomFill;
SetStopSurf(me : mutable; Surf : HSurface from Adaptor3d);
SetAngle(me : mutable; Angle : Real);
Prepare(me:mutable) is private;
SetCurve(me : mutable; C : HCurve from Adaptor3d)
is redefined;
GetCurve(me)
returns HCurve from Adaptor3d
---C++: return const &
is redefined;
SetTrsf(me : mutable; Transfo : Mat from gp)
is redefined;
Copy(me)
returns LocationLaw from GeomFill
is redefined;
D0(me : mutable;
Param: Real;
M : out Mat from gp;
V : out Vec from gp)
---Purpose: compute Location
returns Boolean is redefined;
D0(me : mutable;
Param: Real;
M : out Mat from gp;
V : out Vec from gp;
Poles2d : out Array1OfPnt2d from TColgp)
---Purpose: compute Location and 2d points
returns Boolean is redefined;
D1(me : mutable;
Param: Real;
M : out Mat from gp;
V : out Vec from gp;
DM : out Mat from gp;
DV : out Vec from gp;
Poles2d : out Array1OfPnt2d from TColgp;
DPoles2d : out Array1OfVec2d from TColgp)
---Purpose: compute location 2d points and associated
-- first derivatives.
-- Warning : It used only for C1 or C2 aproximation
returns Boolean
is redefined;
D2(me : mutable;
Param: Real;
M : out Mat from gp;
V : out Vec from gp;
DM : out Mat from gp;
DV : out Vec from gp;
D2M : out Mat from gp;
D2V : out Vec from gp;
Poles2d : out Array1OfPnt2d from TColgp;
DPoles2d : out Array1OfVec2d from TColgp;
D2Poles2d : out Array1OfVec2d from TColgp)
---Purpose: compute location 2d points and associated
-- first and seconde derivatives.
-- Warning : It used only for C2 aproximation
returns Boolean
is redefined;
--
-- ================== General Information On The Function ==================
--
HasFirstRestriction(me)
---Purpose: Say if the first restriction is defined in this class.
-- If it is true the first element of poles array in
-- D0,D1,D2... Correspond to this restriction.
-- Returns Standard_False (default implementation)
returns Boolean
is redefined;
HasLastRestriction(me) -- A FAIRE !!
---Purpose: Say if the last restriction is defined in this class.
-- If it is true the last element of poles array in
-- D0,D1,D2... Correspond to this restriction.
-- Returns Standard_False (default implementation)
returns Boolean
is redefined;
TraceNumber(me)
---Purpose: Give the number of trace (Curves 2d wich are not restriction)
-- Returns 1 (default implementation)
returns Integer
is redefined;
--
-- =================== Management of continuity ===================
--
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>.
-- May be one if Continuity(me) >= <S>
returns Integer is redefined;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is redefined;
SetInterval(me: mutable; First, Last: Real from Standard)
---Purpose: Sets the bounds of the parametric interval on
-- the function
-- This determines the derivatives in these values if the
-- function is not Cn.
is redefined;
GetInterval(me; First, Last: out Real from Standard)
---Purpose: Gets the bounds of the parametric interval on
-- the function
is redefined;
GetDomain(me; First, Last: out Real from Standard)
---Purpose: Gets the bounds of the function parametric domain.
-- Warning: This domain it is not modified by the
-- SetValue method
is redefined;
-- =================== To help computation of Tolerance ===============
--
-- Evaluation of error, in 2d space, or on composed function, is
-- difficult. The following methods can help the approximation to
-- make good evaluation and use good tolerances.
--
-- It is not necessary for the following informations to be very
-- precise. A fast evaluation is sufficient.
Resolution(me;
Index : Integer from Standard;
Tol : Real from Standard;
TolU, TolV : out Real from Standard)
---Purpose: Returns the resolutions in the sub-space 2d <Index>
-- This information is usfull to find an good tolerance in
-- 2d approximation.
-- Warning: Used only if Nb2dCurve > 0
is redefined;
GetMaximalNorm(me : mutable)
---Purpose: Get the maximum Norm of the matrix-location part. It
-- is usful to find an good Tolerance to approx M(t).
returns Real
is redefined;
GetAverageLaw(me : mutable;
AM: out Mat from gp;
AV: out Vec from gp)
---Purpose: Get average value of M(t) and V(t) it is usfull to
-- make fast approximation of rational surfaces.
is redefined;
--
-- To find elementary sweep
--
IsTranslation(me; Error : out Real)
---Purpose: Say if the Location Law, is an translation of Location
-- The default implementation is " returns False ".
returns Boolean
is redefined;
IsRotation(me; Error : out Real )
---Purpose: Say if the Location Law, is a rotation of Location
-- The default implementation is " returns False ".
returns Boolean
is redefined;
Rotation(me; Center : out Pnt from gp)
is redefined;
IsIntersec(me)
---Purpose: Say if the generatrice interset the surface
returns Boolean
is static;
Direction(me)
returns Dir from gp;
fields
Trans : Mat from gp;
myLaw : DraftTrihedron from GeomFill;
mySurf : HSurface from Adaptor3d;
myCurve : HCurve from Adaptor3d;
myTrimmed : HCurve from Adaptor3d;
myDir : Dir from gp;
myAngle : Real from Standard;
myNbPts : Integer from Standard;
myPoles2d : HArray1OfPnt2d from TColgp is protected;
Intersec : Boolean from Standard;
WithTrans : Boolean from Standard;
end LocationDraft;

View File

@@ -0,0 +1,811 @@
// File: GeomFill_LocationDraft.cxx
// Created: Tue Apr 21 17:53:43 1998
// Author: Stephanie HUMEAU
// <shu@sun17>
#include <GeomFill_LocationDraft.ixx>
#include <GeomAdaptor_HCurve.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <Geom_Surface.hxx>
#include <Geom_Line.hxx>
#include <GeomFill_TrihedronLaw.hxx>
#include <GeomFill_FunctionDraft.hxx>
#include <GeomFill_Tensor.hxx>
#include <IntCurveSurface_IntersectionPoint.hxx>
#include <IntCurveSurface_Intersection.hxx>
#include <IntCurveSurface_HInter.hxx>
#include <math_FunctionSetWithDerivatives.hxx>
#include <math_Vector.hxx>
#include <math_NewtonFunctionSetRoot.hxx>
#include <math_Matrix.hxx>
#include <math_Gauss.hxx>
//==================================================================
//Function: GeomFill_LocationDraft
//Purpose : constructor
//==================================================================
GeomFill_LocationDraft::GeomFill_LocationDraft
(const gp_Dir& Direction,
const Standard_Real Angle)
{
myDir = Direction; // direction de depouille
myAngle = Angle; // angle de depouille (teta prime)
mySurf.Nullify();
myLaw = new (GeomFill_DraftTrihedron)(myDir, Angle); // triedre
myNbPts = 41; // nb de points utilises pour les calculs
myPoles2d = new (TColgp_HArray1OfPnt2d)(1, 2*myNbPts);
Intersec = Standard_False; //intersection avec surface d'arret ?
WithTrans = Standard_False;
}
//==================================================================
//Function: Copy
//Purpose :
//==================================================================
Handle(GeomFill_LocationLaw) GeomFill_LocationDraft::Copy() const
{
Handle(GeomFill_TrihedronLaw) law;
law = myLaw->Copy();
Handle(GeomFill_LocationDraft) copy =
new (GeomFill_LocationDraft) (myDir,myAngle);
copy->SetCurve(myCurve);
copy->SetStopSurf(mySurf);
if (WithTrans) copy->SetTrsf(Trans);
return copy;
}
//==================================================================
//Function: SetTrsf
//Purpose :
//==================================================================
void GeomFill_LocationDraft::SetTrsf(const gp_Mat& Transfo)
{
Trans = Transfo;
gp_Mat Aux;
Aux.SetIdentity();
Aux -= Trans;
WithTrans = Standard_False; // Au cas ou Trans = I
for (Standard_Integer ii=1; ii<=3 && !WithTrans ; ii++)
for (Standard_Integer jj=1; jj<=3 && !WithTrans; jj++)
if (Abs(Aux.Value(ii, jj)) > 1.e-14) WithTrans = Standard_True;
}
//==================================================================
//Function: SetCurve
//Purpose : Calcul des poles sur la surfaces d'arret (intersection
// entre la generatrice et la surface en myNbPts points de la section)
//==================================================================
void GeomFill_LocationDraft::SetCurve(const Handle(Adaptor3d_HCurve)& C)
{
myCurve = C;
myTrimmed = C;
myLaw->SetCurve(C);
Prepare();
}
//==================================================================
//Function: SetStopSurf
//Purpose :
//==================================================================
void GeomFill_LocationDraft::SetStopSurf(const Handle(Adaptor3d_HSurface)& Surf)
{
mySurf = Surf;
Prepare();
}
//==================================================================
//Function: SetAngle
//Purpose :
//==================================================================
void GeomFill_LocationDraft::SetAngle(const Standard_Real Angle)
{
myAngle = Angle;
myLaw->SetAngle(myAngle);
Prepare();
}
//==================================================================
//Function: Prepare
//Purpose : Poses les jalon de l'intersection : depouille / Surface
//==================================================================
void GeomFill_LocationDraft::Prepare()
{
if (mySurf.IsNull()) {
Intersec = Standard_False;
return;
}
Intersec = Standard_True;
Standard_Integer ii,jj;
Standard_Real f, l, t;
gp_Pnt P;
gp_Vec D,T,N,B;
Handle(Geom_Line) L;
IntCurveSurface_IntersectionPoint P1,P2;
f = myCurve->FirstParameter();
l = myCurve->LastParameter();
for (ii=1; ii<=myNbPts; ii++)
{
t = Standard_Real(myNbPts - ii)*f + Standard_Real(ii - 1)*l;
t /= (myNbPts-1);
myCurve->D0(t, P);
myLaw->D0(t,T,N,B);
// Generatrice
D = Cos(myAngle)*B + Sin(myAngle)*N;
L = new (Geom_Line) (P, D);
IntCurveSurface_HInter Int; // intersection surface / generatrice
Handle(GeomAdaptor_HCurve) AC = new (GeomAdaptor_HCurve) (L);
Int.Perform(AC, mySurf); // calcul de l'intersection
if (Int.NbPoints() > 0) // il y a au moins 1 intersection
{
P1 = Int.Point(1); // 1er point d'intersection
for (jj=2 ; jj<=Int.NbPoints() ; jj++)
{
P2 = Int.Point(jj);
if(P1.W() > P2.W()) P1 = P2; // point le plus proche
}//for_jj
gp_Pnt2d p (P1.W(), t); // point de la courbe
gp_Pnt2d q (P1.U(),P1.V()); // point sur la surface
myPoles2d->SetValue(2*ii-1,p); // point de la courbe (indice impair)
myPoles2d->SetValue(2*ii,q); // point sur la surface (indice pair)
}
else
{// au moins un point ou il n'y a pas intersection
Intersec = Standard_False;
}
}//for_ii
}
//==================================================================
//Function: GetCurve
//Purpose : return the path
//==================================================================
const Handle(Adaptor3d_HCurve)& GeomFill_LocationDraft::GetCurve() const
{
return myCurve;
}
//==================================================================
//Function: D0
//Purpose :
//==================================================================
Standard_Boolean GeomFill_LocationDraft::D0(const Standard_Real Param,
gp_Mat& M,
gp_Vec& V)
{
Standard_Boolean Ok;
gp_Vec T,N,B;
gp_Pnt P;
myTrimmed->D0(Param, P);
V.SetXYZ(P.XYZ());
Ok = myLaw->D0(Param, T, N, B);
if (!Ok) return Ok;
M.SetCols(N.XYZ(), B.XYZ(), T.XYZ());
if (WithTrans) {
M *= Trans;
}
return Standard_True;
}
//==================================================================
//Function: D0
//Purpose : calcul de l'intersection (C0) sur la surface
//==================================================================
Standard_Boolean GeomFill_LocationDraft::D0(const Standard_Real Param,
gp_Mat& M,
gp_Vec& V,
TColgp_Array1OfPnt2d& Poles2d)
{
Standard_Boolean Ok;
// gp_Vec D,T,N,B,DT,DN,DB;
gp_Vec D,T,N,B;
gp_Pnt P;
myCurve->D0(Param, P);
V.SetXYZ(P.XYZ());
Ok = myLaw->D0(Param, T, N, B);
if (!Ok) return Ok;
M.SetCols(N.XYZ(), B.XYZ(), T.XYZ());
if (WithTrans) {
M *= Trans;
}
if (Intersec == Standard_True) {
// la generatrice intersecte la surface d'arret
// la generatrice
D = Cos(myAngle)*B + Sin(myAngle)*N;
Handle(Geom_Line) L = new (Geom_Line) (P, D);
Handle(GeomAdaptor_HCurve) G = new (GeomAdaptor_HCurve) (L);
Standard_Real t1,t2,Paramt1,t2Param;
Standard_Real U0=0,V0=0,W0=0;
Standard_Integer ii = 1;
// on recherche l'intervalle auquel appartient Param
while (ii<2*myNbPts && myPoles2d->Value(ii).Coord(2) < Param) ii=ii+2;
if (ii<2*myNbPts && !IsEqual(myPoles2d->Value(ii).Coord(2),Param))
{
// interpolation lineaire pour initialiser le germe de la recherche
t1 = myPoles2d->Value(ii).Coord(2);
t2 = myPoles2d->Value(ii-2).Coord(2);
Paramt1 = (Param-t1) / (t2-t1);
t2Param = (t2-Param) / (t2-t1);
W0 = myPoles2d->Value(ii-2).Coord(1)*Paramt1
+ myPoles2d->Value(ii).Coord(1)*t2Param;
U0 = myPoles2d->Value(ii-1).Coord(1)*Paramt1
+ myPoles2d->Value(ii+1).Coord(1)*t2Param;
V0 = myPoles2d->Value(ii-1).Coord(2)*Paramt1
+ myPoles2d->Value(ii+1).Coord(2)*t2Param;
}//if
// on est sur un param ou les points ont deja ete calcules
else if (ii<2*myNbPts && IsEqual(myPoles2d->Value(ii).Coord(2) ,Param))
{
W0 = myPoles2d->Value(ii).Coord(1);
U0 = myPoles2d->Value(ii+1).Coord(1);
V0 = myPoles2d->Value(ii+1).Coord(2);
}//else if
// recherche de la solution (pt d'intersection generatrice / surface)
// point initial
math_Vector X(1,3);
X(1) = W0;
X(2) = U0;
X(3) = V0;
// tolerance sur X
math_Vector XTol(1,3);
XTol.Init(0.00001);
// tolerance sur F
Standard_Real FTol = 0.0000001;
Standard_Integer Iter = 100;
// fonction dont il faut trouver la racine : G(W)-S(U,V)=0
GeomFill_FunctionDraft E(mySurf , G);
// resolution
math_NewtonFunctionSetRoot Result(E, X, XTol, FTol, Iter);
if (Result.IsDone())
{
math_Vector R(1,3);
Result.Root(R); // solution
gp_Pnt2d p (R(2), R(3)); // point sur la surface
gp_Pnt2d q (R(1), Param); // point de la courbe
Poles2d.SetValue(1,p);
Poles2d.SetValue(2,q);
}
else {
return Standard_False;
}
}// if_Intersec
// la generatrice n'intersecte pas la surface d'arret
return Standard_True;
}
//==================================================================
//Function: D1
//Purpose : calcul de l'intersection (C1) sur la surface
//==================================================================
Standard_Boolean GeomFill_LocationDraft::D1(const Standard_Real Param,
gp_Mat& M,
gp_Vec& V,
gp_Mat& DM,
gp_Vec& DV,
TColgp_Array1OfPnt2d& Poles2d,
TColgp_Array1OfVec2d& DPoles2d)
{
Standard_Boolean Ok;
gp_Vec D,T,N,B,DT,DN,DB;
gp_Pnt P;
myCurve->D1(Param, P, DV);
V.SetXYZ(P.XYZ());
Ok = myLaw->D1(Param, T, DT, N, DN, B, DB);
if (!Ok) return Standard_False;
M.SetCols(N.XYZ(), B.XYZ(), T.XYZ());
DM.SetCols(DN.XYZ(), DB.XYZ(), DT.XYZ());
if (WithTrans) {
M *= Trans;
DM *= Trans;
}
if (Intersec == Standard_True)
{ // la generatrice intersecte la surface d'arret
// la generatrice
D = Cos(myAngle)*B + Sin(myAngle)*N;
Handle(Geom_Line) L = new (Geom_Line) (P, D);
Handle(GeomAdaptor_HCurve) G = new (GeomAdaptor_HCurve) (L);
Standard_Real t1,t2,Paramt1,t2Param;
Standard_Real U0=0,V0=0,W0=0;
Standard_Integer ii = 1;
// recherche de la solution (pt d'intersection generatrice / surface)
// on recherche l'intervalle auquel appartient Param
while (ii < 2*myNbPts && myPoles2d->Value(ii).Coord(2) < Param) ii=ii+2;
if (ii < 2*myNbPts && !IsEqual(myPoles2d->Value(ii).Coord(2) ,Param))
{
// interpolation lineaire pour initialiser le germe de la recherche
t1 = myPoles2d->Value(ii).Coord(2);
t2 = myPoles2d->Value(ii-2).Coord(2);
Paramt1 = (Param-t1) / (t2-t1);
t2Param = (t2-Param) / (t2-t1);
W0 = myPoles2d->Value(ii-2).Coord(1)*Paramt1
+ myPoles2d->Value(ii).Coord(1)*t2Param;
U0 = myPoles2d->Value(ii-1).Coord(1)*Paramt1
+ myPoles2d->Value(ii+1).Coord(1)*t2Param;
V0 = myPoles2d->Value(ii-1).Coord(2)*Paramt1
+ myPoles2d->Value(ii+1).Coord(2)*t2Param;
}//if
else if (ii<2*myNbPts && IsEqual(myPoles2d->Value(ii).Coord(2) ,Param))
{
W0 = myPoles2d->Value(ii).Coord(1);
U0 = myPoles2d->Value(ii+1).Coord(1);
V0 = myPoles2d->Value(ii+1).Coord(2);
}//else if
// germe
math_Vector X(1,3);
X(1) = W0;
X(2) = U0;
X(3) = V0;
// tolerance sur X
math_Vector XTol(1,3);
XTol.Init(0.0001);
// tolerance sur F
Standard_Real FTol = 0.000001;
Standard_Integer Iter = 100;
// fonction dont il faut trouver la racine : G(W)-S(U,V)=0
GeomFill_FunctionDraft E(mySurf,G);
// resolution
math_NewtonFunctionSetRoot Result (E, X, XTol, FTol, Iter);
if (Result.IsDone())
{
math_Vector R(1,3);
Result.Root(R); // solution
gp_Pnt2d p (R(2), R(3)); // point sur la surface
gp_Pnt2d q (R(1), Param); // point de la courbe
Poles2d.SetValue(1,p);
Poles2d.SetValue(2,q);
// derivee de la fonction par rapport a Param
math_Vector DEDT(1,3,0);
E.DerivT(myTrimmed, Param, R(1), DN, myAngle, DEDT); // dE/dt => DEDT
math_Vector DSDT (1,3,0);
math_Matrix DEDX (1,3,1,3,0);
E.Derivatives(R, DEDX); // dE/dx au point R => DEDX
// resolution du syst. lin. : DEDX*DSDT = -DEDT
math_Gauss Ga(DEDX);
if (Ga.IsDone())
{
Ga.Solve (DEDT.Opposite(), DSDT); // resolution du syst. lin.
gp_Vec2d dp (DSDT(2), DSDT(3)); // surface
gp_Vec2d dq (DSDT(1), 1); // courbe
DPoles2d.SetValue(1, dp);
DPoles2d.SetValue(2, dq);
}//if
}//if_Result
else {// la generatrice n'intersecte pas la surface d'arret
return Standard_False;
}
}// if_Intersec
return Standard_True;
}
//==================================================================
//Function: D2
//Purpose : calcul de l'intersection (C2) sur la surface
//==================================================================
Standard_Boolean GeomFill_LocationDraft::D2(const Standard_Real Param,
gp_Mat& M,
gp_Vec& V,
gp_Mat& DM,
gp_Vec& DV,
gp_Mat& D2M,
gp_Vec& D2V,
TColgp_Array1OfPnt2d& Poles2d,
TColgp_Array1OfVec2d& DPoles2d,
TColgp_Array1OfVec2d& D2Poles2d)
{
Standard_Boolean Ok;
gp_Vec D,T,N,B,DT,DN,DB,D2T,D2N,D2B;
gp_Pnt P;
myCurve->D2(Param, P, DV, D2V);
V.SetXYZ(P.XYZ());
Ok = myLaw->D2(Param, T, DT, D2T, N, DN, D2N, B, DB, D2B);
if (!Ok) return Ok;
M.SetCols(N.XYZ(), B.XYZ(), T.XYZ());
DM.SetCols(DN.XYZ(), DB.XYZ(), DT.XYZ());
D2M.SetCols(D2N.XYZ(), D2B.XYZ(), D2T.XYZ());
if (WithTrans) {
M *= Trans;
DM *= Trans;
D2M *= Trans;
}
if (Intersec == Standard_True)
{// la generatrice intersecte la surface d'arret
// la generatrice
D = Cos(myAngle) * B + Sin(myAngle) * N;
Handle(Geom_Line) L = new (Geom_Line) (P, D);
Handle(GeomAdaptor_HCurve) G = new (GeomAdaptor_HCurve) (L);
Standard_Real t1,t2,Paramt1,t2Param;
Standard_Real U0=0,V0=0,W0=0;
Standard_Integer ii = 1;
// on recherche l'intervalle auquel appartient Param
while (ii<2*myNbPts && myPoles2d->Value(ii).Coord(2) < Param) ii=ii+2;
if (ii<2*myNbPts && !IsEqual(myPoles2d->Value(ii).Coord(2) ,Param))
{
// interpolation lineaire pour initialiser le germe de la recherche
t1 = myPoles2d->Value(ii).Coord(2);
t2 = myPoles2d->Value(ii-2).Coord(2);
Paramt1 = (Param-t1) / (t2-t1);
t2Param = (t2-Param) / (t2-t1);
W0 = myPoles2d->Value(ii-2).Coord(1)*Paramt1 +
myPoles2d->Value(ii).Coord(1)*t2Param;
U0 = myPoles2d->Value(ii-1).Coord(1)*Paramt1 +
myPoles2d->Value(ii+1).Coord(1)*t2Param;
V0 = myPoles2d->Value(ii-1).Coord(2)*Paramt1 +
myPoles2d->Value(ii+1).Coord(2)*t2Param;
}//if
else if (ii<2*myNbPts && IsEqual(myPoles2d->Value(ii).Coord(2) ,Param))
{
W0 = myPoles2d->Value(ii).Coord(1);
U0 = myPoles2d->Value(ii+1).Coord(1);
V0 = myPoles2d->Value(ii+1).Coord(2);
}//else if
// recherche de la solution (pt d'intersection generatrice / surface)
// germe
math_Vector X(1,3);
X(1) = W0;
X(2) = U0;
X(3) = V0;
// tolerance sur X
math_Vector XTol(1,3);
XTol.Init(0.0001);
// tolerance sur F
Standard_Real FTol = 0.000001;
Standard_Integer Iter = 150;
// fonction dont il faut trouver la racine : G(W)-S(U,V)=0
GeomFill_FunctionDraft E(mySurf,G);
// resolution
math_NewtonFunctionSetRoot Result (E, X, XTol, FTol, Iter);
if (Result.IsDone())
{
math_Vector R(1,3);
Result.Root(R); // solution
// solution
gp_Pnt2d p (R(2), R(3)); // point sur la surface
gp_Pnt2d q (R(1), Param); // point de la courbe
Poles2d.SetValue(1,p);
Poles2d.SetValue(2,q);
// premiere derivee de la fonction
math_Vector DEDT(1,3,0);
E.DerivT(myTrimmed, Param, R(1), DN, myAngle, DEDT); // dE/dt => DEDT
math_Vector DSDT (1,3,0);
math_Matrix DEDX (1,3,1,3,0);
E.Derivatives(R, DEDX); // dE/dx => DEDX
// resolution du syst. lin.
math_Gauss Ga (DEDX);
if (Ga.IsDone())
{
Ga.Solve (DEDT.Opposite(), DSDT);
gp_Vec2d dp (DSDT(2), DSDT(3)); // surface
gp_Vec2d dq (DSDT(1), 1); // courbe
DPoles2d.SetValue(1, dp);
DPoles2d.SetValue(2, dq);
}//if
// deuxieme derivee
GeomFill_Tensor D2EDX2(3,3,3);
E.Deriv2X(R, D2EDX2); // d2E/dx2
math_Vector D2EDT2(1,3,0);
E.Deriv2T(myTrimmed, Param, R(1), D2N, myAngle ,D2EDT2); // d2E/dt2
math_Matrix D2EDTDX(1,3,1,3,0);
E.DerivTX(DN, myAngle, D2EDTDX); // d2E/dtdx
math_Vector D2SDT2(1,3,0); // d2s/dt2
math_Matrix T(1,3,1,3,0);
D2EDX2.Multiply(DSDT,T);
// resolution du syst. lin.
math_Gauss Ga1 (DEDX);
if (Ga1.IsDone())
{
Ga1.Solve ( -T*DSDT - 2*D2EDTDX*DSDT - D2EDT2 , D2SDT2);
gp_Vec2d d2p (D2SDT2(2), D2SDT2(3)); // surface
gp_Vec2d d2q (D2SDT2(1), 0); // courbe
D2Poles2d.SetValue(1, d2p);
D2Poles2d.SetValue(2, d2q);
}//if
else {// la generatrice n'intersecte pas la surface d'arret
return Standard_False;
}
}//if_Result
} //if_Intersec
return Standard_True;
}
//==================================================================
//Function : HasFirstRestriction
//Purpose :
//==================================================================
Standard_Boolean GeomFill_LocationDraft::HasFirstRestriction() const
{
return Standard_False;
}
//==================================================================
//Function : HasLastRestriction
//Purpose :
//==================================================================
Standard_Boolean GeomFill_LocationDraft::HasLastRestriction() const
{
if (Intersec == Standard_True) return Standard_True;
else return Standard_False;
}
//==================================================================
//Function : TraceNumber
//Purpose :
//==================================================================
Standard_Integer GeomFill_LocationDraft::TraceNumber() const
{
if (Intersec == Standard_True) return 1;
else return 0;
}
//==================================================================
//Function:NbIntervals
//Purpose :
//==================================================================
Standard_Integer GeomFill_LocationDraft::NbIntervals
(const GeomAbs_Shape S) const
{
return myLaw->NbIntervals(S);
}
//==================================================================
//Function:Intervals
//Purpose :
//==================================================================
void GeomFill_LocationDraft::Intervals(TColStd_Array1OfReal& T,
const GeomAbs_Shape S) const
{
myLaw->Intervals(T, S);
}
//==================================================================
//Function:SetInterval
//Purpose :
//==================================================================
void GeomFill_LocationDraft::SetInterval(const Standard_Real First,
const Standard_Real Last)
{
myLaw->SetInterval( First, Last);
myTrimmed = myCurve->Trim( First, Last, 0);
}
//==================================================================
//Function: GetInterval
//Purpose :
//==================================================================
void GeomFill_LocationDraft::GetInterval(Standard_Real& First,
Standard_Real& Last) const
{
First = myTrimmed->FirstParameter();
Last = myTrimmed->LastParameter();
}
//==================================================================
//Function: GetDomain
//Purpose :
//==================================================================
void GeomFill_LocationDraft::GetDomain(Standard_Real& First,
Standard_Real& Last) const
{
First = myCurve->FirstParameter();
Last = myCurve->LastParameter();
}
//==================================================================
//function : Resolution
//purpose :
//==================================================================
void GeomFill_LocationDraft::Resolution (const Standard_Integer Index,
const Standard_Real Tol,
Standard_Real& TolU,
Standard_Real& TolV) const
{
if (Index==1) {
TolU = mySurf->UResolution(Tol);
TolV = mySurf->VResolution(Tol);
}
else {
TolU = Tol;
TolV = Tol;
}
}
//==================================================================
//Function:GetMaximalNorm
//Purpose : On suppose les triedres normes => return 1
//==================================================================
Standard_Real GeomFill_LocationDraft::GetMaximalNorm()
{
return 1.;
}
//==================================================================
//Function:GetAverageLaw
//Purpose :
//==================================================================
void GeomFill_LocationDraft::GetAverageLaw(gp_Mat& AM,
gp_Vec& AV)
{
Standard_Integer ii;
Standard_Real U, delta;
gp_Vec V1,V2,V3, V;
myLaw->GetAverageLaw(V1, V2, V3);
AM.SetCols(V1.XYZ(), V2.XYZ(), V3.XYZ());
AV.SetCoord(0., 0., 0.);
delta = (myTrimmed->LastParameter() - myTrimmed->FirstParameter())/10;
U= myTrimmed->FirstParameter();
for (ii=0; ii<=10; ii++, U+=delta) {
V.SetXYZ( myTrimmed->Value(U).XYZ() );
AV += V;
}
AV /= 11;
}
//==================================================================
//Function : IsTranslation
//Purpose :
//==================================================================
// Standard_Boolean GeomFill_LocationDraft::IsTranslation(Standard_Real& Error) const
Standard_Boolean GeomFill_LocationDraft::IsTranslation(Standard_Real& ) const
{
return myLaw->IsConstant();
}
//==================================================================
//Function : IsRotation
//Purpose :
//==================================================================
Standard_Boolean GeomFill_LocationDraft::IsRotation(Standard_Real& Error) const
{
GeomAbs_CurveType Type;
Error = 0;
Type = myCurve->GetType();
if (Type == GeomAbs_Circle) {
return myLaw->IsOnlyBy3dCurve();
}
return Standard_False;
}
//==================================================================
//Function : Rotation
//Purpose :
//==================================================================
void GeomFill_LocationDraft::Rotation(gp_Pnt& Centre) const
{
Centre = myCurve->Circle().Location();
}
//==================================================================
//Function : IsIntersec
//Purpose :
//==================================================================
Standard_Boolean GeomFill_LocationDraft::IsIntersec() const
{
return Intersec;
}
//==================================================================
//Function : Direction
//Purpose :
//==================================================================
gp_Dir GeomFill_LocationDraft::Direction() const
{
return myDir;
}

View File

@@ -0,0 +1,293 @@
-- File: GeomFill_LocationGuide.cdl
-- Created: Wed Jul 8 15:11:44 1998
-- Author: Stephanie HUMEAU
-- <shu@sun17>
---Copyright: Matra Datavision 1998
class LocationGuide from GeomFill
inherits LocationLaw from GeomFill
uses
HCurve from Adaptor3d,
Mat from gp,
Vec from gp,
Pnt from gp,
Shape from GeomAbs,
Array1OfReal from TColStd,
Array1OfVec2d from TColgp,
Array1OfPnt2d from TColgp,
HArray1OfPnt2d from TColgp,
HArray2OfPnt2d from TColgp,
HArray1OfReal from TColStd,
HSurface from Adaptor3d,
Curve from Geom,
Curve from Adaptor3d,
TrihedronWithGuide from GeomFill,
Dir from gp,
Line from Geom,
TrimmedCurve from Geom,
SectionLaw from GeomFill,
PipeError from GeomFill,
Vector from math
raises
NotImplemented, ConstructionError, OutOfRange
is
Create(Triedre : TrihedronWithGuide from GeomFill)
returns LocationGuide from GeomFill;
Set (me : mutable;
Section : SectionLaw from GeomFill;
rotat : Boolean from Standard;
SFirst, SLast : Real;
PrecAngle : Real;
LastAngle : out Real)
is static;
EraseRotation(me : mutable);
SetRotation(me : mutable;
PrecAngle : Real;
LastAngle : out Real)
is private;
SetCurve(me : mutable; C : HCurve from Adaptor3d)
is redefined;
GetCurve(me)
returns HCurve from Adaptor3d
---C++: return const &
is redefined;
SetTrsf(me : mutable; Transfo : Mat from gp)
is redefined;
Copy(me)
returns LocationLaw from GeomFill
is redefined;
D0(me : mutable;
Param: Real;
M : out Mat from gp;
V : out Vec from gp)
---Purpose: compute Location
returns Boolean is redefined;
D0(me : mutable;
Param: Real;
M : out Mat from gp;
V : out Vec from gp;
Poles2d : out Array1OfPnt2d from TColgp)
---Purpose: compute Location and 2d points
returns Boolean is redefined;
D1(me : mutable;
Param: Real;
M : out Mat from gp;
V : out Vec from gp;
DM : out Mat from gp;
DV : out Vec from gp;
Poles2d : out Array1OfPnt2d from TColgp;
DPoles2d : out Array1OfVec2d from TColgp)
---Purpose: compute location 2d points and associated
-- first derivatives.
-- Warning : It used only for C1 or C2 aproximation
returns Boolean
is redefined;
D2(me : mutable;
Param: Real;
M : out Mat from gp;
V : out Vec from gp;
DM : out Mat from gp;
DV : out Vec from gp;
D2M : out Mat from gp;
D2V : out Vec from gp;
Poles2d : out Array1OfPnt2d from TColgp;
DPoles2d : out Array1OfVec2d from TColgp;
D2Poles2d : out Array1OfVec2d from TColgp)
---Purpose: compute location 2d points and associated
-- first and seconde derivatives.
-- Warning : It used only for C2 aproximation
returns Boolean
is redefined;
-- ================== General Information On The Function ==================
--
HasFirstRestriction(me)
---Purpose: Say if the first restriction is defined in this class.
-- If it is true the first element of poles array in
-- D0,D1,D2... Correspond to this restriction.
-- Returns Standard_False (default implementation)
returns Boolean
is redefined;
HasLastRestriction(me) -- A FAIRE !!
---Purpose: Say if the last restriction is defined in this class.
-- If it is true the last element of poles array in
-- D0,D1,D2... Correspond to this restriction.
-- Returns Standard_False (default implementation)
returns Boolean
is redefined;
TraceNumber(me)
---Purpose: Give the number of trace (Curves 2d wich are not restriction)
-- Returns 1 (default implementation)
returns Integer
is redefined;
ErrorStatus(me)
---Purpose:Give a status to the Law
-- Returns PipeOk (default implementation)
returns PipeError from GeomFill
is redefined;
--
-- =================== Management of continuity ===================
--
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>.
-- May be one if Continuity(me) >= <S>
returns Integer is redefined;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is redefined;
SetInterval(me: mutable; First, Last: Real from Standard)
---Purpose: Sets the bounds of the parametric interval on
-- the function
-- This determines the derivatives in these values if the
-- function is not Cn.
is redefined;
GetInterval(me; First, Last: out Real from Standard)
---Purpose: Gets the bounds of the parametric interval on
-- the function
is redefined;
GetDomain(me; First, Last: out Real from Standard)
---Purpose: Gets the bounds of the function parametric domain.
-- Warning: This domain it is not modified by the
-- SetValue method
is redefined;
-- =================== To help computation of Tolerance ===============
--
-- Evaluation of error, in 2d space, or on composed function, is
-- difficult. The following methods can help the approximation to
-- make good evaluation and use good tolerances.
--
-- It is not necessary for the following informations to be very
-- precise. A fast evaluation is sufficient.
SetTolerance(me : mutable; Tol3d, Tol2d : Real)
---Purpose: Is usefull, if (me) have to run numerical
-- algorithm to perform D0, D1 or D2
-- The default implementation make nothing.
is redefined;
Resolution(me;
Index : Integer from Standard;
Tol : Real from Standard;
TolU, TolV : out Real from Standard)
---Purpose: Returns the resolutions in the sub-space 2d <Index>
-- This information is usfull to find an good tolerance in
-- 2d approximation.
-- Warning: Used only if Nb2dCurve > 0
is redefined;
GetMaximalNorm(me : mutable)
---Purpose: Get the maximum Norm of the matrix-location part. It
-- is usful to find an good Tolerance to approx M(t).
returns Real
is redefined;
GetAverageLaw(me : mutable;
AM: out Mat from gp;
AV: out Vec from gp)
---Purpose: Get average value of M(t) and V(t) it is usfull to
-- make fast approximation of rational surfaces.
is redefined;
--
-- To find elementary sweep
--
IsTranslation(me; Error : out Real)
---Purpose: Say if the Location Law, is an translation of Location
-- The default implementation is " returns False ".
returns Boolean
is redefined;
IsRotation(me; Error : out Real )
---Purpose: Say if the Location Law, is a rotation of Location
-- The default implementation is " returns False ".
returns Boolean
is redefined;
Rotation(me; Center : out Pnt from gp)
is redefined;
Section(me)
returns Curve from Geom;
Guide(me)
returns HCurve from Adaptor3d;
InitX(me;
Param : Real from Standard)
is private;
SetOrigine(me : mutable;
Param1 : Real;
Param2 : Real)
is static;
fields
myLaw : TrihedronWithGuide from GeomFill; -- loi de triedre
mySec : SectionLaw from GeomFill; -- loi de section
myCurve : HCurve from Adaptor3d; -- trajectoire
myGuide : HCurve from Adaptor3d; -- guide
myTrimmed : HCurve from Adaptor3d; -- trajectoire trimme
myPoles2d : HArray2OfPnt2d from TColgp is protected;
myNbPts : Integer from Standard;
rotation : Boolean from Standard; -- contact ou non
OrigParam1 : Real from Standard; -- pour ACR
OrigParam2 : Real from Standard;
Uf, Ul : Real from Standard;
myFirstS : Real from Standard;
myLastS : Real from Standard;
ratio : Real from Standard;
WithTrans: Boolean from Standard;
Trans : Mat from gp;
TolRes : Vector from math;
Inf, Sup: Vector from math;
X, R : Vector from math;
myStatus : PipeError from GeomFill;
end LocationGuide;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,240 @@
-- File: GeomFill_LocationLaw.cdl
-- Created: Thu Nov 20 17:53:46 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
deferred class LocationLaw from GeomFill inherits TShared from MMgt
---Purpose: To define location law in Sweeping location is --
-- defined by an Matrix M and an Vector V, and
-- transform an point P in MP+V.
uses
HCurve from Adaptor3d,
Mat from gp,
Vec from gp,
Pnt from gp,
Shape from GeomAbs,
Array1OfReal from TColStd,
Array1OfPnt2d from TColgp,
Array1OfVec2d from TColgp,
PipeError from GeomFill,
Shape from GeomAbs
raises
NotImplemented, OutOfRange
is
SetCurve(me : mutable; C : HCurve from Adaptor3d)
is deferred;
GetCurve(me)
returns HCurve from Adaptor3d
---C++: return const &
is deferred;
SetTrsf(me : mutable; Transfo : Mat from gp)
---Purpose: Set a transformation Matrix like the law M(t) become
-- Mat * M(t)
is deferred;
Copy(me)
returns LocationLaw from GeomFill
is deferred;
--
--========== To compute Location and derivatives Location
--
D0(me : mutable;
Param: Real;
M : out Mat from gp;
V : out Vec from gp)
---Purpose: compute Location
returns Boolean is deferred;
D0(me : mutable;
Param: Real;
M : out Mat from gp;
V : out Vec from gp;
Poles2d : out Array1OfPnt2d from TColgp)
---Purpose: compute Location and 2d points
returns Boolean is deferred;
D1(me : mutable;
Param: Real;
M : out Mat from gp;
V : out Vec from gp;
DM : out Mat from gp;
DV : out Vec from gp;
Poles2d : out Array1OfPnt2d from TColgp;
DPoles2d : out Array1OfVec2d from TColgp)
---Purpose: compute location 2d points and associated
-- first derivatives.
-- Warning : It used only for C1 or C2 aproximation
returns Boolean
raises NotImplemented
is virtual;
D2(me : mutable;
Param: Real;
M : out Mat from gp;
V : out Vec from gp;
DM : out Mat from gp;
DV : out Vec from gp;
D2M : out Mat from gp;
D2V : out Vec from gp;
Poles2d : out Array1OfPnt2d from TColgp;
DPoles2d : out Array1OfVec2d from TColgp;
D2Poles2d : out Array1OfVec2d from TColgp)
---Purpose: compute location 2d points and associated
-- first and seconde derivatives.
-- Warning : It used only for C2 aproximation
returns Boolean
raises NotImplemented
is virtual;
--
-- ================== General Information On The Function ==================
--
Nb2dCurves(me)
---Purpose: get the number of 2d curves (Restrictions + Traces)
-- to approximate.
returns Integer is static;
HasFirstRestriction(me)
---Purpose: Say if the first restriction is defined in this class.
-- If it is true the first element of poles array in
-- D0,D1,D2... Correspond to this restriction.
-- Returns Standard_False (default implementation)
returns Boolean
is virtual;
HasLastRestriction(me)
---Purpose: Say if the last restriction is defined in this class.
-- If it is true the last element of poles array in
-- D0,D1,D2... Correspond to this restriction.
-- Returns Standard_False (default implementation)
returns Boolean
is virtual;
TraceNumber(me)
---Purpose: Give the number of trace (Curves 2d wich are not restriction)
-- Returns 0 (default implementation)
returns Integer
is virtual;
ErrorStatus(me)
---Purpose:Give a status to the Law
-- Returns PipeOk (default implementation)
returns PipeError from GeomFill
is virtual;
--
-- =================== Management of continuity ===================
--
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>.
-- May be one if Continuity(me) >= <S>
returns Integer is deferred;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is deferred;
SetInterval(me: mutable; First, Last: Real from Standard)
---Purpose: Sets the bounds of the parametric interval on
-- the function
-- This determines the derivatives in these values if the
-- function is not Cn.
is deferred;
GetInterval(me; First, Last: out Real from Standard)
---Purpose: Gets the bounds of the parametric interval on
-- the function
is deferred;
GetDomain(me; First, Last: out Real from Standard)
---Purpose: Gets the bounds of the function parametric domain.
-- Warning: This domain it is not modified by the
-- SetValue method
is deferred;
-- =================== To help computation of Tolerance ===============
--
-- Evaluation of error, in 2d space, or on composed function, is
-- difficult. The following methods can help the approximation to
-- make good evaluation and use good tolerances.
--
-- It is not necessary for the following informations to be very
-- precise. A fast evaluation is sufficient.
Resolution(me;
Index : Integer from Standard;
Tol : Real from Standard;
TolU, TolV : out Real from Standard)
---Purpose: Returns the resolutions in the sub-space 2d <Index>
-- This information is usfull to find an good tolerance in
-- 2d approximation.
---Warning: Used only if Nb2dCurve > 0
raises NotImplemented
is virtual;
SetTolerance(me : mutable; Tol3d, Tol2d : Real)
---Purpose: Is usefull, if (me) have to run numerical
-- algorithm to perform D0, D1 or D2
-- The default implementation make nothing.
is virtual;
GetMaximalNorm(me : mutable)
---Purpose: Get the maximum Norm of the matrix-location part. It
-- is usful to find an good Tolerance to approx M(t).
returns Real
is deferred;
GetAverageLaw(me : mutable;
AM: out Mat from gp;
AV: out Vec from gp)
---Purpose: Get average value of M(t) and V(t) it is usfull to
-- make fast approximation of rational surfaces.
is deferred;
--
-- To find elementary sweep
--
IsTranslation(me; Error : out Real)
---Purpose: Say if the Location Law, is an translation of Location
-- The default implementation is " returns False ".
returns Boolean
is virtual;
IsRotation(me; Error : out Real)
---Purpose: Say if the Location Law, is a rotation of Location
-- The default implementation is " returns False ".
returns Boolean
is virtual;
Rotation(me; Center : out Pnt from gp)
raises NotImplemented
is virtual;
end LocationLaw;

View File

@@ -0,0 +1,81 @@
// File: GeomFill_LocationLaw.cxx
// Created: Fri Nov 21 15:19:24 1997
// Author: Philippe MANGIN
// <pmn@sgi29>
#include <GeomFill_LocationLaw.ixx>
Standard_Boolean GeomFill_LocationLaw::D1(const Standard_Real, gp_Mat&, gp_Vec&,gp_Mat&, gp_Vec&,TColgp_Array1OfPnt2d&,TColgp_Array1OfVec2d&)
{
Standard_NotImplemented::Raise("GeomFill_LocationLaw::D1");
return 0;
}
Standard_Boolean GeomFill_LocationLaw::D2(const Standard_Real,
gp_Mat&,gp_Vec&,
gp_Mat&, gp_Vec&,
gp_Mat&, gp_Vec&,
TColgp_Array1OfPnt2d&,TColgp_Array1OfVec2d&,TColgp_Array1OfVec2d&)
{
Standard_NotImplemented::Raise("GeomFill_LocationLaw::D2");
return 0;
}
Standard_Integer GeomFill_LocationLaw::Nb2dCurves() const
{
Standard_Integer N = TraceNumber();
if (HasFirstRestriction()) N++;
if (HasLastRestriction()) N++;
return N;
}
Standard_Boolean GeomFill_LocationLaw::HasFirstRestriction() const
{
return Standard_False;
}
Standard_Boolean GeomFill_LocationLaw::HasLastRestriction() const
{
return Standard_False;
}
Standard_Integer GeomFill_LocationLaw::TraceNumber() const
{
return 0;
}
//==================================================================
//Function : ErrorStatus
//Purpose :
//==================================================================
GeomFill_PipeError GeomFill_LocationLaw::ErrorStatus() const
{
return GeomFill_PipeOk;
}
// void GeomFill_LocationLaw::Resolution(const Standard_Integer Index,const Standard_Real Tol,Standard_Real& TolU,Standard_Real& TolV) const
void GeomFill_LocationLaw::Resolution(const Standard_Integer ,const Standard_Real ,Standard_Real& ,Standard_Real& ) const
{
Standard_NotImplemented::Raise("GeomFill_LocationLaw::Resolution");
}
void GeomFill_LocationLaw::SetTolerance(const Standard_Real,
const Standard_Real )
{
// Ne fait rien !!
}
Standard_Boolean GeomFill_LocationLaw::IsTranslation(Standard_Real&) const
{
return Standard_False;
}
Standard_Boolean GeomFill_LocationLaw::IsRotation(Standard_Real&) const
{
return Standard_False;
}
void GeomFill_LocationLaw::Rotation(gp_Pnt&) const
{
Standard_NotImplemented::Raise("GeomFill_SectionLaw::Rotation");
}

View File

@@ -0,0 +1,275 @@
-- File: GeomFill_NSections.cdl
-- Created: Mon Dec 14 15:37:49 1998
-- Author: Joelle CHAUVET
-- <jct@sgi64>
---Copyright: Matra Datavision 1998
class NSections from GeomFill inherits SectionLaw from GeomFill
---Purpose: Define a Section Law by N Sections
uses
Curve from Geom,
SequenceOfCurve from TColGeom,
BSplineSurface from Geom,
BSplineCurve from Geom,
Function from Law,
Shape from GeomAbs,
Pnt from gp,
Array1OfPnt from TColgp,
Array1OfVec from TColgp,
Array1OfInteger from TColStd,
Array1OfReal from TColStd,
SequenceOfReal from TColStd
raises
OutOfRange
is
Create(NC : SequenceOfCurve from TColGeom)
---Purpose: Make a SectionLaw with N Curves.
returns NSections from GeomFill;
Create(NC : SequenceOfCurve from TColGeom;
NP : SequenceOfReal from TColStd)
---Purpose: Make a SectionLaw with N Curves and N associated parameters.
returns NSections from GeomFill;
Create(NC : SequenceOfCurve from TColGeom;
NP : SequenceOfReal from TColStd;
UF, UL : Real from Standard)
---Purpose: Make a SectionLaw with N Curves and N associated parameters.
-- UF and UL are the parametric bounds of the NSections
returns NSections from GeomFill;
Create(NC : SequenceOfCurve from TColGeom;
NP : SequenceOfReal from TColStd;
UF, UL, VF, VL : Real from Standard)
---Purpose: Make a SectionLaw with N Curves and N associated parameters.
-- UF and UL are the parametric bounds of the NSections
-- VF and VL are the parametric bounds of the path
returns NSections from GeomFill;
Create(NC : SequenceOfCurve from TColGeom;
NP : SequenceOfReal from TColStd;
UF, UL, VF, VL : Real from Standard;
Surf : BSplineSurface from Geom)
---Purpose: Make a SectionLaw with N Curves and N associated parameters.
-- UF and UL are the parametric bounds of the NSections
-- VF and VL are the parametric bounds of the path
-- UF and UL are the parametric bounds of the NSections
-- Surf is a reference surface used by BRepFill_NSections
returns NSections from GeomFill;
--
--========== To compute Sections and derivatives Sections
--
D0(me : mutable;
Param: Real;
Poles : out Array1OfPnt from TColgp;
Weigths : out Array1OfReal from TColStd)
---Purpose: compute the section for v = param
returns Boolean is redefined;
D1(me : mutable;
Param: Real;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
Weigths : out Array1OfReal from TColStd;
DWeigths : out Array1OfReal from TColStd)
---Purpose: compute the first derivative in v direction of the
-- section for v = param
-- Warning : It used only for C1 or C2 aproximation
returns Boolean
is redefined;
D2(me : mutable;
Param: Real;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
D2Poles : out Array1OfVec from TColgp;
Weigths : out Array1OfReal from TColStd;
DWeigths : out Array1OfReal from TColStd;
D2Weigths : out Array1OfReal from TColStd)
---Purpose: compute the second derivative in v direction of the
-- section for v = param
-- Warning : It used only for C2 aproximation
returns Boolean
is redefined;
SetSurface(me: mutable; RefSurf: BSplineSurface from Geom)
---Purpose: Sets the reference surface
--
;
ComputeSurface(me: mutable)
---Purpose: Computes the surface
--
;
BSplineSurface(me)
---Purpose: give if possible an bspline Surface, like iso-v are the
-- section. If it is not possible this methode have to
-- get an Null Surface. Is it the default implementation.
returns BSplineSurface from Geom
is redefined;
SectionShape(me; NbPoles : out Integer from Standard;
NbKnots : out Integer from Standard;
Degree : out Integer from Standard)
---Purpose: get the format of an section
is redefined;
Knots(me; TKnots: out Array1OfReal from TColStd)
---Purpose: get the Knots of the section
is redefined;
Mults(me; TMults: out Array1OfInteger from TColStd)
---Purpose: get the Multplicities of the section
is redefined;
IsRational(me)
---Purpose: Returns if the sections are rationnal or not
returns Boolean is redefined;
IsUPeriodic(me)
---Purpose: Returns if the sections are periodic or not
returns Boolean is redefined;
IsVPeriodic(me)
---Purpose: Returns if the law isperiodic or not
returns Boolean is redefined;
--
-- =================== Management of continuity ===================
--
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>.
-- May be one if Continuity(me) >= <S>
returns Integer is redefined;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is redefined;
SetInterval(me: mutable; First, Last: Real from Standard)
---Purpose: Sets the bounds of the parametric interval on
-- the function
-- This determines the derivatives in these values if the
-- function is not Cn.
is redefined;
GetInterval(me; First, Last: out Real from Standard)
---Purpose: Gets the bounds of the parametric interval on
-- the function
is redefined;
GetDomain(me; First, Last: out Real from Standard)
---Purpose: Gets the bounds of the function parametric domain.
-- Warning: This domain it is not modified by the
-- SetValue method
is redefined;
-- ===================== To help computation of Tolerance ======
-- Evaluation of error, in 2d space, or on rational function, is
-- difficult. The following methods can help the approximation to
-- make good evaluation and use good tolerances.
--
-- It is not necessary for the following informations to be very
-- precise. A fast evaluation is sufficient.
GetTolerance(me;
BoundTol, SurfTol, AngleTol : Real;
Tol3d : out Array1OfReal)
---Purpose: Returns the tolerances associated at each poles to
-- reach in approximation, to satisfy: BoundTol error
-- at the Boundary AngleTol tangent error at the
-- Boundary (in radian) SurfTol error inside the
-- surface.
is redefined;
BarycentreOfSurf(me)
---Purpose: Get the barycentre of Surface.
-- An very poor estimation is sufficent.
-- This information is usefull to perform well
-- conditioned rational approximation.
-- Warning: Used only if <me> IsRational
returns Pnt from gp
is redefined;
MaximalSection(me) returns Real
---Purpose: Returns the length of the greater section. This
-- information is usefull to G1's control.
-- Warning: With an little value, approximation can be slower.
is redefined;
GetMinimalWeight(me; Weigths : out Array1OfReal from TColStd)
---Purpose: Compute the minimal value of weight for each poles
-- in all sections.
-- This information is usefull to control error
-- in rational approximation.
-- Warning: Used only if <me> IsRational
is redefined;
--- Particular case
IsConstant(me; Error : out Real)
---Purpose: return True If the Law isConstant
returns Boolean
is redefined;
ConstantSection(me)
---Purpose: Return the constant Section if <me> IsConstant.
--
returns Curve from Geom
is redefined;
IsConicalLaw(me; Error : out Real)
---Purpose: Returns True if all section are circle, with same
-- plane,same center and linear radius evolution
-- Return False by Default.
returns Boolean
is redefined;
CirclSection(me; Param : Real)
---Purpose: Return the circle section at parameter <Param>, if
-- <me> a IsConicalLaw
returns Curve from Geom
raises OutOfRange from Standard -- If <me> is not a Conical Law
is redefined;
fields
UFirst, ULast, VFirst, VLast : Real;
mySections : SequenceOfCurve from TColGeom;
myParams : SequenceOfReal from TColStd;
mySurface : BSplineSurface from Geom;
myRefSurf : BSplineSurface from Geom;
end NSections;

View File

@@ -0,0 +1,995 @@
// File: GeomFill_NSections.cxx
// Created: Mon Dec 14 15:38:23 1998
// Author: Joelle CHAUVET
// <jct@sgi64>
// Modified: Fri Jan 8 15:47:20 1999
// Author: Joelle CHAUVET
// <jct@sgi64>
// enfin un calcul exact pour D1 et D2
// le calcul par differ. finies est garde dans verifD1 et verifD2
// Modified: Mon Jan 18 11:06:46 1999
// Author: Joelle CHAUVET
// <jct@sgi64>
// mise au point de D1, D2 et IsConstant
#include <stdio.h>
#include <GeomFill_NSections.ixx>
#include <GeomFill_SectionGenerator.hxx>
#include <GeomFill_Line.hxx>
#include <GeomFill_AppSurf.hxx>
#include <GeomConvert.hxx>
#include <Convert_ParameterisationType.hxx>
#include <Geom_Geometry.hxx>
#include <Geom_Surface.hxx>
#include <Geom_BSplineSurface.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_Circle.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomAdaptor_Surface.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <TColgp_Array2OfPnt.hxx>
#include <TColGeom_Array1OfCurve.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <BSplCLib.hxx>
#include <Precision.hxx>
#include <gp_Lin.hxx>
#include <gp_Circ.hxx>
#ifdef DEB
# ifdef DRAW
# include <DrawTrSurf.hxx>
# endif
static Standard_Boolean Affich = 0;
static Standard_Integer NbSurf = 0;
#endif
#ifdef DEB
// verification des fonctions de derivation D1 et D2 par differences finies
Standard_Boolean verifD1(const TColgp_Array1OfPnt& P1,
const TColStd_Array1OfReal& W1,
const TColgp_Array1OfPnt& P2,
const TColStd_Array1OfReal& W2,
const TColgp_Array1OfVec& DPoles,
const TColStd_Array1OfReal& DWeights,
const Standard_Real pTol,
const Standard_Real wTol,
const Standard_Real pas)
{
Standard_Boolean ok = Standard_True;
Standard_Integer ii, L = P1.Length();
Standard_Real dw;
gp_Vec dP;
for (ii=1; ii<=L; ii++) {
dw = (W2(ii)-W1(ii)) / pas;
if (Abs(dw-DWeights(ii))>wTol) {
if (Affich) {
cout<<"erreur dans la derivee 1ere du poids pour l'indice "<<ii<<endl;
cout<<"par diff finies : "<<dw<<endl;
cout<<"resultat obtenu : "<<DWeights(ii)<<endl;
}
ok = Standard_False;
}
dP.SetXYZ( (P2(ii).XYZ()- P1(ii).XYZ()) /pas );
gp_Vec diff = dP - DPoles(ii);
if (diff.Magnitude()>pTol) {
if (Affich) {
cout<<"erreur dans la derivee 1ere du pole pour l'indice "<<ii<<endl;
cout<<"par diff finies : ("<<dP.X()
<<" "<<dP.Y()
<<" "<<dP.Z()<<")"<<endl;
cout<<"resultat obtenu : ("<<DPoles(ii).X()
<<" "<<DPoles(ii).Y()
<<" "<<DPoles(ii).Z()<<")"<<endl;
}
ok = Standard_False;
}
}
return ok;
}
Standard_Boolean verifD2(const TColgp_Array1OfVec& DP1,
const TColStd_Array1OfReal& DW1,
const TColgp_Array1OfVec& DP2,
const TColStd_Array1OfReal& DW2,
const TColgp_Array1OfVec& D2Poles,
const TColStd_Array1OfReal& D2Weights,
const Standard_Real pTol,
const Standard_Real wTol,
const Standard_Real pas)
{
Standard_Boolean ok = Standard_True;;
Standard_Integer ii, L = DP1.Length();
Standard_Real d2w;
gp_Vec d2P;
for (ii=1; ii<=L; ii++) {
Standard_Real dw1 = DW1(ii), dw2 = DW2(ii);
d2w = (dw2-dw1) / pas;
if (Abs(d2w-D2Weights(ii))>wTol) {
if (Affich) {
cout<<"erreur dans la derivee 2nde du poids pour l'indice "<<ii<<endl;
cout<<"par diff finies : "<<d2w<<endl;
cout<<"resultat obtenu : "<<D2Weights(ii)<<endl;
}
ok = Standard_False;
}
d2P.SetXYZ( (DP2(ii).XYZ()- DP1(ii).XYZ()) /pas );
gp_Vec diff = d2P - D2Poles(ii);
if (diff.Magnitude()>pTol) {
if (Affich) {
cout<<"erreur dans la derivee 2nde du pole pour l'indice "<<ii<<endl;
cout<<"par diff finies : ("<<d2P.X()
<<" "<<d2P.Y()
<<" "<<d2P.Z()<<")"<<endl;
cout<<"resultat obtenu : ("<<D2Poles(ii).X()
<<" "<<D2Poles(ii).Y()
<<" "<<D2Poles(ii).Z()<<")"<<endl;
}
ok = Standard_False;
}
}
return ok;
}
#endif
// fonction d'evaluation des poles et des poids de mySurface pour D1 et D2
static void ResultEval(const Handle_Geom_BSplineSurface& surf,
const Standard_Real V,
const Standard_Integer deriv,
TColStd_Array1OfReal& Result)
{
Standard_Boolean rational = surf->IsVRational() ;
Standard_Integer gap = 3;
if ( rational ) gap++;
Standard_Integer Cdeg = surf->VDegree(),
Cdim = surf->NbUPoles() * gap,
NbP = surf->NbVPoles();
// les noeuds plats
Standard_Integer Ksize = NbP + Cdeg + 1;
TColStd_Array1OfReal FKnots(1,Ksize);
surf->VKnotSequence(FKnots);
// les poles
Standard_Integer Psize = Cdim * NbP;
TColStd_Array1OfReal SPoles(1,Psize);
Standard_Integer ii, jj, ipole=1;
for (jj=1;jj<=NbP;jj++) {
for (ii=1;ii<=surf->NbUPoles();ii++) {
SPoles(ipole) = surf->Pole(ii,jj).X();
SPoles(ipole+1) = surf->Pole(ii,jj).Y();
SPoles(ipole+2) = surf->Pole(ii,jj).Z();
if (rational) {
SPoles(ipole+3) = surf->Weight(ii,jj);
SPoles(ipole) *= SPoles(ipole+3);
SPoles(ipole+1) *= SPoles(ipole+3);
SPoles(ipole+2) *= SPoles(ipole+3);
}
ipole+=gap;
}
}
Standard_Real * Padr = (Standard_Real *) &SPoles(1);
Standard_Boolean periodic_flag = Standard_False ;
Standard_Integer extrap_mode[2];
extrap_mode[0] = extrap_mode[1] = Cdeg;
TColStd_Array1OfReal EvalBS(1, Cdim * (deriv+1)) ;
Standard_Real * Eadr = (Standard_Real *) &EvalBS(1) ;
BSplCLib::Eval(V,periodic_flag,deriv,extrap_mode[0],
Cdeg,FKnots,Cdim,*Padr,*Eadr);
for (ii=1;ii<=Cdim;ii++) {
Result(ii) = EvalBS(ii+deriv*Cdim);
}
}
//=======================================================================
//function : GeomFill_NSections
//purpose :
//=======================================================================
GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC)
{
mySections = NC;
myRefSurf.Nullify();
ComputeSurface();
}
//=======================================================================
//function : GeomFill_NSections
//purpose :
//=======================================================================
GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
const TColStd_SequenceOfReal& NP)
{
mySections = NC;
myParams = NP;
UFirst = 0.;
ULast = 1.;
VFirst = 0.;
VLast = 1.;
myRefSurf.Nullify();
ComputeSurface();
}
//=======================================================================
//function : GeomFill_NSections
//purpose :
//=======================================================================
GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
const TColStd_SequenceOfReal& NP,
const Standard_Real UF,
const Standard_Real UL,
const Standard_Real VF,
const Standard_Real VL)
{
mySections = NC;
myParams = NP;
UFirst = UF;
ULast = UL;
VFirst = VF;
VLast = VL;
myRefSurf.Nullify();
ComputeSurface();
}
//=======================================================================
//function : GeomFill_NSections
//purpose :
//=======================================================================
GeomFill_NSections::GeomFill_NSections(const TColGeom_SequenceOfCurve& NC,
const TColStd_SequenceOfReal& NP,
const Standard_Real UF,
const Standard_Real UL,
const Standard_Real VF,
const Standard_Real VL,
const Handle(Geom_BSplineSurface)& Surf)
{
mySections = NC;
myParams = NP;
UFirst = UF;
ULast = UL;
VFirst = VF;
VLast = VL;
myRefSurf = Surf;
ComputeSurface();
}
//=======================================================
// Purpose :D0
//=======================================================
Standard_Boolean GeomFill_NSections::D0(const Standard_Real V,
TColgp_Array1OfPnt& Poles,
TColStd_Array1OfReal& Weights)
{
if (mySurface.IsNull()) {
return Standard_False;
}
else {
Handle(Geom_BSplineCurve) Curve
= Handle(Geom_BSplineCurve)::DownCast(mySurface->VIso( V, Standard_False ));
TColgp_Array1OfPnt poles(1,mySurface->NbUPoles());
TColStd_Array1OfReal weights(1,mySurface->NbUPoles());
Curve->Poles(poles);
Curve->Weights(weights);
Standard_Integer ii, L = Poles.Length();
for (ii=1; ii<=L; ii++) {
Poles(ii).SetXYZ(poles(ii).XYZ());
Weights(ii) = weights(ii);
}
}
return Standard_True;
}
//=======================================================
// Purpose :D1
//=======================================================
Standard_Boolean GeomFill_NSections::D1(const Standard_Real V,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfVec& DPoles,
TColStd_Array1OfReal& Weights,
TColStd_Array1OfReal& DWeights)
{
if (mySurface.IsNull() ) return Standard_False;
Standard_Boolean ok = D0(V,Poles,Weights);
if (!ok) return Standard_False;
Standard_Integer L = Poles.Length(), derivative_request = 1;
Standard_Boolean rational = mySurface->IsVRational() ;
Standard_Integer gap = 3;
if (rational) gap++;
Standard_Integer dimResult = mySurface->NbUPoles() * gap;
Handle(Geom_BSplineSurface) surf_deper;
if (mySurface->IsVPeriodic()) {
surf_deper = Handle(Geom_BSplineSurface)::DownCast(mySurface->Copy());
surf_deper->SetVNotPeriodic();
dimResult = surf_deper->NbUPoles() * gap;
}
TColStd_Array1OfReal Result(1,dimResult);
if (mySurface->IsVPeriodic()) {
ResultEval(surf_deper,V,derivative_request,Result);
}
else {
ResultEval(mySurface,V,derivative_request,Result);
}
Standard_Real ww, EpsW = 10*Precision::PConfusion();
Standard_Boolean NullWeight = Standard_False;
if (!rational) DWeights.Init(0.);
Standard_Integer indice = 1, ii;
// recopie des poles du resultat sous forme de points 3D et de poids
for (ii=1; ii<=L && (!NullWeight) ; ii++) {
DPoles(ii).SetX( Result(indice) );
DPoles(ii).SetY( Result(indice+1) );
DPoles(ii).SetZ( Result(indice+2) );
if (rational) {
ww = Weights(ii);
if (ww < EpsW) {
NullWeight = Standard_True;
}
else {
DWeights(ii) = Result(indice+3);
DPoles(ii)
.SetXYZ( ( DPoles(ii).XYZ()-DWeights(ii)*Poles(ii).Coord() ) / ww );
}
}
indice += gap;
}
if (NullWeight) return Standard_False;
// verif par diff finies sous debug sauf pour les surfaces periodiques
#ifdef DEB
if (!mySurface->IsVPeriodic()) {
Standard_Real pas = 1.e-6, wTol = 1.e-4, pTol = 1.e-3;
Standard_Real V1,V2;
Standard_Boolean ok1,ok2;
TColStd_Array1OfReal W1(1,L),W2(1,L);
TColgp_Array1OfPnt P1(1,L),P2(1,L);
gp_Pnt nul(0.,0.,0.);
W1.Init(0.);
W2.Init(0.);
P1.Init(nul);
P2.Init(nul);
V1 = V;
V2 = V+pas;
ok1 = D0(V1,P1,W1);
ok2 = D0(V2,P2,W2);
if (!ok1 || !ok2) cout<<"probleme en D0"<<endl;
Standard_Boolean check = verifD1(P1,W1,P2,W2,DPoles,DWeights,pTol,wTol,pas);
if (!check) cout<<"D1 incorrecte en V = "<<V<<endl;
}
#endif
return Standard_True;
}
//=======================================================
// Purpose :D2
//=======================================================
Standard_Boolean GeomFill_NSections::D2(const Standard_Real V,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfVec& DPoles,
TColgp_Array1OfVec& D2Poles,
TColStd_Array1OfReal& Weights,
TColStd_Array1OfReal& DWeights,
TColStd_Array1OfReal& D2Weights)
{
if (mySurface.IsNull() ) return Standard_False;
// pb dans BSplCLib::Eval() pour les surfaces rationnelles de degre 1
// si l'ordre de derivation est egal a 2.
if (mySurface->VDegree()<2) return Standard_False;
Standard_Boolean ok = D1(V,Poles,DPoles,Weights,DWeights);
if (!ok) return Standard_False;
Standard_Integer L = Poles.Length(), derivative_request = 2;
Standard_Boolean rational = mySurface->IsVRational() ;
Standard_Integer gap = 3;
if (rational) gap++;
Standard_Integer dimResult = mySurface->NbUPoles() * gap;
Handle(Geom_BSplineSurface) surf_deper;
if (mySurface->IsVPeriodic()) {
surf_deper = Handle(Geom_BSplineSurface)::DownCast(mySurface->Copy());
surf_deper->SetVNotPeriodic();
dimResult = surf_deper->NbUPoles() * gap;
}
TColStd_Array1OfReal Result(1,dimResult);
if (mySurface->IsVPeriodic()) {
ResultEval(surf_deper,V,derivative_request,Result);
}
else {
ResultEval(mySurface,V,derivative_request,Result);
}
Standard_Real ww, EpsW = 10*Precision::PConfusion();
Standard_Boolean NullWeight = Standard_False;
if (!rational) D2Weights.Init(0.);
Standard_Integer indice = 1, ii;
// recopie des poles du resultat sous forme de points 3D et de poids
for (ii=1; ii<=L && (!NullWeight) ; ii++) {
D2Poles(ii).SetX( Result(indice) );
D2Poles(ii).SetY( Result(indice+1) );
D2Poles(ii).SetZ( Result(indice+2) );
if (rational) {
ww = Weights(ii);
if (ww < EpsW) {
NullWeight = Standard_True;
}
else {
D2Weights(ii) = Result(indice+3);
D2Poles(ii)
.SetXYZ( ( D2Poles(ii).XYZ() - D2Weights(ii)*Poles(ii).Coord()
- 2*DWeights(ii)*DPoles(ii).XYZ() ) / ww );
}
}
indice += gap;
}
if (NullWeight) return Standard_False;
// verif par diff finies sous debug sauf pour les surfaces periodiques
#ifdef DEB
if (!mySurface->IsVPeriodic()) {
Standard_Real V1,V2;
Standard_Boolean ok1,ok2;
Standard_Real pas = 1.e-6, wTol = 1.e-4, pTol = 1.e-3;
TColStd_Array1OfReal W1(1,L),W2(1,L),DW1(1,L),DW2(1,L);
TColgp_Array1OfPnt P1(1,L),P2(1,L);
TColgp_Array1OfVec DP1(1,L),DP2(1,L);
gp_Pnt nul(0.,0.,0.);
gp_Vec Vnul(0.,0.,0.);
W1.Init(0.);
W2.Init(0.);
DW1.Init(0.);
DW2.Init(0.);
P1.Init(nul);
P2.Init(nul);
DP1.Init(Vnul);
DP2.Init(Vnul);
V1 = V;
V2 = V+pas;
ok1 = D1(V1,P1,DP1,W1,DW1);
ok2 = D1(V2,P2,DP2,W2,DW2);
if (!ok1 || !ok2) cout<<"probleme en D0 ou en D1"<<endl;
Standard_Boolean check = verifD2(DP1,DW1,DP2,DW2,D2Poles,D2Weights,pTol,wTol,pas);
if (!check) cout<<"D2 incorrecte en V = "<<V<<endl;
}
#endif
return Standard_True;
}
//=======================================================
// Purpose :BSplineSurface()
//=======================================================
Handle(Geom_BSplineSurface)
GeomFill_NSections::BSplineSurface() const
{
return mySurface;
}
//=======================================================
// Purpose :SetSurface()
//=======================================================
void GeomFill_NSections::SetSurface(const Handle(Geom_BSplineSurface)& RefSurf)
{
myRefSurf = RefSurf;
}
//=======================================================
// Purpose :ComputeSurface()
//=======================================================
void GeomFill_NSections::ComputeSurface()
{
Handle(Geom_BSplineSurface) BS;
if (myRefSurf.IsNull()) {
Standard_Boolean s1Point = Standard_False;
Standard_Boolean s2Point = Standard_False;
Standard_Boolean vClosed = Standard_False;
Standard_Real myPres3d = 1.e-06;
Standard_Integer i,j,jdeb=1,jfin=mySections.Length();
GeomFill_SectionGenerator section;
Handle(Geom_BSplineSurface) surface;
Handle(Geom_TrimmedCurve) curvTrim;
Handle(Geom_BSplineCurve) curvBS, curvBS1;
Handle(Geom_Curve) curv = mySections(1);
Standard_Real first = curv->FirstParameter(),
last = curv->LastParameter();
if (s1Point) {
jdeb++;
TColgp_Array1OfPnt Extremities(1,2);
Extremities(1) = curv->Value(first);
Extremities(2) = curv->Value(last);
TColStd_Array1OfReal Bounds(1,2);
Bounds(1) = UFirst;
Bounds(2) = ULast;
Standard_Real Deg = 1;
TColStd_Array1OfInteger Mult(1,2);
Mult(1) = (Standard_Integer ) Deg+1;
Mult(2) = (Standard_Integer ) Deg+1;
Handle(Geom_BSplineCurve) BSPoint
= new Geom_BSplineCurve(Extremities,Bounds,Mult,(Standard_Integer ) Deg);
section.AddCurve(BSPoint);
}
if (s2Point) {
jfin--;
}
// Standard_Boolean urat = Standard_True;
for (j=jdeb; j<=jfin; j++) {
// cas des sections bouclantes
if (j==jfin && vClosed) {
section.AddCurve(curvBS1);
}
else {
// read the j-th curve
curv = mySections(j);
curvTrim = new Geom_TrimmedCurve(curv,
curv->FirstParameter(),
curv->LastParameter());
// transformation en BSpline reparametree sur [UFirst,ULast]
curvBS = Handle(Geom_BSplineCurve)::DownCast(curvTrim);
if (curvBS.IsNull()) {
Convert_ParameterisationType ParamType = Convert_QuasiAngular;
curvBS = GeomConvert::CurveToBSplineCurve(curvTrim,ParamType);
}
TColStd_Array1OfReal BSK(1,curvBS->NbKnots());
curvBS->Knots(BSK);
BSplCLib::Reparametrize(UFirst,ULast,BSK);
curvBS->SetKnots(BSK);
// if (!curvBS->IsRational()) urat = Standard_False;
section.AddCurve(curvBS);
// cas des sections bouclantes
if (j==jdeb && vClosed) {
curvBS1 = curvBS;
}
}
}
if (s2Point) {
curv = mySections(jfin+1);
first = curv->FirstParameter();
last = curv->LastParameter();
TColgp_Array1OfPnt Extremities(1,2);
Extremities(1) = curv->Value(first);
Extremities(2) = curv->Value(last);
TColStd_Array1OfReal Bounds(1,2);
Bounds(1) = UFirst;
Bounds(2) = ULast;
Standard_Real Deg = 1;
TColStd_Array1OfInteger Mult(1,2);
Mult(1) = (Standard_Integer ) Deg+1;
Mult(2) = (Standard_Integer ) Deg+1;
Handle(Geom_BSplineCurve) BSPoint
= new Geom_BSplineCurve(Extremities,Bounds,Mult,(Standard_Integer ) Deg);
section.AddCurve(BSPoint);
}
Standard_Integer Nbcurves = mySections.Length();
Standard_Integer Nbpar = myParams.Length();
Handle(TColStd_HArray1OfReal) HPar
= new TColStd_HArray1OfReal(1,Nbpar);
for (i=1;i<=Nbpar;i++) {
HPar->SetValue(i,myParams(i));
}
section.SetParam(HPar);
section.Perform(Precision::PConfusion());
Handle(GeomFill_Line) line = new GeomFill_Line(Nbcurves);
Standard_Integer nbIt = 0, degmin = 2, degmax = 6;
Standard_Boolean knownP = Standard_True;
GeomFill_AppSurf anApprox(degmin, degmax, myPres3d, myPres3d, nbIt, knownP);
Standard_Boolean SpApprox = Standard_True;
anApprox.Perform(line, section, SpApprox);
BS =
new Geom_BSplineSurface(anApprox.SurfPoles(), anApprox.SurfWeights(),
anApprox.SurfUKnots(), anApprox.SurfVKnots(),
anApprox.SurfUMults(), anApprox.SurfVMults(),
anApprox.UDegree(), anApprox.VDegree());
}
else {
// segmentation de myRefSurf
Standard_Real Ui1, Ui2, V0, V1;
BS = Handle(Geom_BSplineSurface)::DownCast(myRefSurf->Copy());
Ui1 = UFirst;
Ui2 = ULast;
Standard_Integer i1, i2;
myRefSurf->LocateU( Ui1, Precision::PConfusion(), i1, i2 );
if (Abs(Ui1 - myRefSurf->UKnot(i1)) <= Precision::PConfusion())
Ui1 = myRefSurf->UKnot(i1);
if (Abs(Ui1 - myRefSurf->UKnot(i2)) <= Precision::PConfusion())
Ui1 = myRefSurf->UKnot(i2);
myRefSurf->LocateU( Ui2, Precision::PConfusion(), i1, i2 );
if (Abs(Ui2 - myRefSurf->UKnot(i1)) <= Precision::PConfusion())
Ui2 = myRefSurf->UKnot(i1);
if (Abs(Ui2 - myRefSurf->UKnot(i2)) <= Precision::PConfusion())
Ui2 = myRefSurf->UKnot(i2);
V0 = myRefSurf->VKnot(myRefSurf->FirstVKnotIndex());
V1 = myRefSurf->VKnot(myRefSurf->LastVKnotIndex());
BS->CheckAndSegment(Ui1,Ui2,V0,V1);
}
mySurface = BS;
// On augmente le degre pour que le positionnement D2 soit correct
if (mySurface->VDegree()<2) {
mySurface->IncreaseDegree(mySurface->UDegree(),2);
}
#ifdef DEB
NbSurf++;
if (Affich) {
#ifdef DRAW
char name[256];
sprintf(name,"NS_Surf_%d",NbSurf);
DrawTrSurf::Set(name,BS);
cout<<endl<<"RESULTAT de ComputeSurface : NS_Surf_"<<NbSurf<<endl<<endl;
#endif
}
#endif
}
//=======================================================
// Purpose :SectionShape
//=======================================================
void GeomFill_NSections::SectionShape(Standard_Integer& NbPoles,
Standard_Integer& NbKnots,
Standard_Integer& Degree) const
{
NbPoles = mySurface->NbUPoles();
NbKnots = mySurface->NbUKnots();
Degree = mySurface->UDegree();
}
//=======================================================
// Purpose :Knots
//=======================================================
void GeomFill_NSections::Knots(TColStd_Array1OfReal& TKnots) const
{
mySurface->UKnots(TKnots);
}
//=======================================================
// Purpose :Mults
//=======================================================
void GeomFill_NSections::Mults(TColStd_Array1OfInteger& TMults) const
{
mySurface->UMultiplicities(TMults);
}
//=======================================================
// Purpose :IsRational
//=======================================================
Standard_Boolean GeomFill_NSections::IsRational() const
{
return mySurface->IsURational();
}
//=======================================================
// Purpose :IsUPeriodic
//=======================================================
Standard_Boolean GeomFill_NSections::IsUPeriodic() const
{
return mySurface->IsUPeriodic();
}
//=======================================================
// Purpose :IsVPeriodic
//=======================================================
Standard_Boolean GeomFill_NSections::IsVPeriodic() const
{
return mySurface->IsVPeriodic();
}
//=======================================================
// Purpose :NbIntervals
//=======================================================
Standard_Integer GeomFill_NSections::NbIntervals(const GeomAbs_Shape S) const
{
GeomAdaptor_Surface AdS(mySurface);
return AdS.NbVIntervals(S);
}
//=======================================================
// Purpose :Intervals
//=======================================================
void GeomFill_NSections::Intervals(TColStd_Array1OfReal& T,
const GeomAbs_Shape S) const
{
GeomAdaptor_Surface AdS(mySurface);
AdS.VIntervals(T,S);
}
//=======================================================
// Purpose : SetInterval
//=======================================================
// void GeomFill_NSections::SetInterval(const Standard_Real F,
void GeomFill_NSections::SetInterval(const Standard_Real ,
// const Standard_Real L)
const Standard_Real )
{
// rien a faire : mySurface est supposee Cn en V
}
//=======================================================
// Purpose : GetInterval
//=======================================================
void GeomFill_NSections::GetInterval(Standard_Real& F,
Standard_Real& L) const
{
F = VFirst;
L = VLast;
}
//=======================================================
// Purpose : GetDomain
//=======================================================
void GeomFill_NSections::GetDomain(Standard_Real& F,
Standard_Real& L) const
{
F = VFirst;
L = VLast;
}
//=======================================================
// Purpose : GetTolerance
//=======================================================
void GeomFill_NSections::GetTolerance(const Standard_Real BoundTol,
const Standard_Real SurfTol,
// const Standard_Real AngleTol,
const Standard_Real ,
TColStd_Array1OfReal& Tol3d) const
{
Tol3d.Init(SurfTol);
if (BoundTol<SurfTol) {
Tol3d(Tol3d.Lower()) = BoundTol;
Tol3d(Tol3d.Upper()) = BoundTol;
}
}
//=======================================================
// Purpose : BarycentreOfSurf
//=======================================================
gp_Pnt GeomFill_NSections::BarycentreOfSurf() const
{
gp_Pnt P, Bary;
Bary.SetCoord(0., 0., 0.);
Standard_Integer ii,jj;
Standard_Real U0, U1, V0, V1;
mySurface->Bounds(U0,U1,V0,V1);
Standard_Real V = V0, DeltaV = ( V1 - V0 ) / 20;
Standard_Real U = U0, DeltaU = ( U1 - U0 ) / 20;
for(jj=0;jj<=20;jj++,V+=DeltaV) {
for (ii=0 ; ii <=20; ii++, U+=DeltaU) {
P = mySurface->Value(U,V);
Bary.ChangeCoord() += P.XYZ();
}
}
Bary.ChangeCoord() /= (21*21);
return Bary;
}
//=======================================================
// Purpose : MaximalSection
//=======================================================
Standard_Real GeomFill_NSections::MaximalSection() const
{
Standard_Real L, Lmax=0.;
Standard_Integer ii;
for (ii=1; ii <=mySections.Length(); ii++) {
GeomAdaptor_Curve AC (mySections(ii));
L = GCPnts_AbscissaPoint::Length(AC);
if (L>Lmax) Lmax = L;
}
return Lmax;
}
//=======================================================
// Purpose : GetMinimalWeight
//=======================================================
void GeomFill_NSections::GetMinimalWeight(TColStd_Array1OfReal& Weights) const
{
if (mySurface->IsURational()) {
Standard_Integer NbU = mySurface->NbUPoles(),
NbV = mySurface->NbVPoles();
TColStd_Array2OfReal WSurf(1,NbU,1,NbV);
mySurface->Weights(WSurf);
Standard_Integer i,j;
for (i=1;i<=NbU;i++) {
Standard_Real min = WSurf(i,1);
for (j=2;j<=NbV;j++) {
if (min> WSurf(i,j)) min = WSurf(i,j);
}
Weights.SetValue(i,min);
}
}
else {
Weights.Init(1);
}
}
//=======================================================
// Purpose : IsConstant
//=======================================================
Standard_Boolean GeomFill_NSections::IsConstant(Standard_Real& Error) const
{
// on se limite a 2 sections
Standard_Boolean isconst = (mySections.Length()==2);
Standard_Real Err = 0.;
if (isconst) {
GeomAdaptor_Curve AC1(mySections(1));
GeomAbs_CurveType CType = AC1.GetType();
GeomAdaptor_Curve AC2(mySections(2));
// les sections doivent avoir le meme type
isconst = ( AC2.GetType() == CType);
if (isconst) {
if (CType == GeomAbs_Circle) {
gp_Circ C1 = AC1.Circle();
gp_Circ C2 = AC2.Circle();
Standard_Real Tol = 1.e-7;
Standard_Boolean samedir, samerad, samepos;
samedir = (C1.Axis().IsParallel(C2.Axis(),1.e-4));
samerad = (Abs(C1.Radius()-C2.Radius())<Tol);
samepos = (C1.Location().Distance(C2.Location())<Tol);
if (!samepos) {
gp_Ax1 D(C1.Location(),gp_Vec(C1.Location(),C2.Location()));
samepos = (C1.Axis().IsParallel(D,1.e-4));
}
isconst = samedir && samerad && samepos;
}
else if (CType == GeomAbs_Line) {
gp_Lin L1 = AC1.Line();
gp_Lin L2 = AC2.Line();
Standard_Real Tol = 1.e-7;
Standard_Boolean samedir, samelength, samepos;
samedir = (L1.Direction().IsParallel(L2.Direction(),1.e-4));
gp_Pnt P11 = AC1.Value(AC1.FirstParameter()),
P12 = AC1.Value(AC1.LastParameter()),
P21 = AC2.Value(AC2.FirstParameter()),
P22 = AC2.Value(AC2.LastParameter());
samelength = (Abs(P11.Distance(P12)-P21.Distance(P22))<Tol);
// l'ecart entre les 2 sections ne compte pas
samepos = ( ( P11.Distance(P21)<Tol && P12.Distance(P22)<Tol )
|| ( P12.Distance(P21)<Tol && P11.Distance(P22)<Tol ) );
//samepos = Standard_True;
isconst = samedir && samelength && samepos;
}
else {
isconst = Standard_False;
}
}
}
Error = Err;
return isconst;
}
//=======================================================
// Purpose : ConstantSection
//=======================================================
Handle(Geom_Curve) GeomFill_NSections::ConstantSection() const
{
// Standard_Real Err;
// if (!IsConstant(Err)) StdFail_NotDone::Raise("The Law is not Constant!");
Handle(Geom_Curve) C;
C = Handle(Geom_Curve)::DownCast( mySections(1)->Copy());
return C;
}
//=======================================================
// Purpose : IsConicalLaw
//=======================================================
Standard_Boolean GeomFill_NSections::IsConicalLaw(Standard_Real& Error) const
{
Standard_Boolean isconic = (mySections.Length()==2);
Standard_Real Err = 0.;
if (isconic) {
GeomAdaptor_Curve AC1(mySections(1));
GeomAdaptor_Curve AC2(mySections(2));
isconic = ( AC1.GetType() == GeomAbs_Circle )
&& ( AC2.GetType() == GeomAbs_Circle ) ;
if (isconic) {
gp_Circ C1 = AC1.Circle();
gp_Circ C2 = AC2.Circle();
Standard_Real Tol = 1.e-7;
Standard_Boolean samedir, linearrad, sameaxis;
samedir = (C1.Axis().IsParallel(C2.Axis(),1.e-4));
// pour 2 sections, la variation du rayon est forcement lineaire
linearrad = Standard_True;
// formule plus generale pour 3 sections au moins
// Standard_Real param0 = C2.Radius()*myParams(1) - C1.Radius()*myParams(2);
// param0 = param0 / (C2.Radius()-C1.Radius()) ;
// linearrad = ( Abs( C3.Radius()*myParams(1)-C1.Radius()*myParams(3)
// - param0*(C3.Radius()-C1.Radius()) ) < Tol);
sameaxis = (C1.Location().Distance(C2.Location())<Tol);
if (!sameaxis) {
gp_Ax1 D(C1.Location(),gp_Vec(C1.Location(),C2.Location()));
sameaxis = (C1.Axis().IsParallel(D,1.e-4));
}
isconic = samedir && linearrad && sameaxis;
//// Modified by jgv, 18.02.2009 for OCC20866 ////
Standard_Real first1 = AC1.FirstParameter(), last1 = AC1.LastParameter();
Standard_Real first2 = AC2.FirstParameter(), last2 = AC2.LastParameter();
isconic = (Abs(first1-first2) <= Precision::PConfusion() &&
Abs(last1-last2) <= Precision::PConfusion());
//////////////////////////////////////////////////
}
}
Error = Err;
return isconic;
}
//=======================================================
// Purpose : CirclSection
//=======================================================
Handle(Geom_Curve) GeomFill_NSections::CirclSection(const Standard_Real V) const
{
Standard_Real Err;
if (!IsConicalLaw(Err)) StdFail_NotDone::Raise("The Law is not Conical!");
GeomAdaptor_Curve AC1(mySections(1));
GeomAdaptor_Curve AC2(mySections(mySections.Length()));
gp_Circ C1 = AC1.Circle();
gp_Circ C2 = AC2.Circle();
Standard_Real p1 = myParams(1), p2 = myParams(myParams.Length());
Standard_Real radius = ( C2.Radius() - C1.Radius() ) * (V - p1) / (p2 - p1)
+ C1.Radius();
C1.SetRadius(radius);
Handle(Geom_Curve) C = new (Geom_Circle) (C1);
if (! AC1.IsPeriodic()) {
Handle(Geom_Curve) Cbis = new (Geom_TrimmedCurve)
(C, AC1.FirstParameter(), AC1.LastParameter());
C = Cbis;
}
return C;
}

371
src/GeomFill/GeomFill_Pipe.cdl Executable file
View File

@@ -0,0 +1,371 @@
-- File: GeomFill_Pipe.cdl
-- Created: Wed Apr 13 13:59:08 1994
-- Author: Eric BONNARDEL
-- <ebo@fuegox>
---Copyright: Matra Datavision 1994
class Pipe from GeomFill
---Purpose: Describes functions to construct pipes. A pipe is built by
-- sweeping a curve (the section) along another curve (the path).
-- The Pipe class provides the following types of construction:
-- - pipes with a circular section of constant radius,
-- - pipes with a constant section,
-- - pipes with a section evolving between two given curves.
-- All standard specific cases are detected in order to build,
-- where required, a plane, cylinder, cone, sphere, torus,
-- surface of linear extrusion or surface of revolution.
-- Generally speaking, the result is a BSpline surface (NURBS).
-- A Pipe object provides a framework for:
-- - defining the pipe to be built,
-- - implementing the construction algorithm, and
-- - consulting the resulting surface.
-- There are several methods to instantiate a Pipe:
-- 1) give a path and a radius : the section is
-- a circle. This location is the first point
-- of the path, and this direction is the first
-- derivate (calculate at the first point ) of
-- the path.
--
-- 2) give a path and a section.
-- Differtent options are available
-- 2.a) Use the classical Frenet trihedron
-- - or the CorrectedFrenet trihedron
-- (To avoid twisted surface)
-- - or a constant trihedron to have all the sections
-- in a same plane
-- 2.b) Define a ConstantBinormal Direction to keep the
-- same angle beetween the Direction and the sections
-- along the sweep surface.
-- 2.c) Define the path by a surface and a 2dcurve,
-- the surface is used to define the trihedron's normal.
-- It is usefull to keep a constant angle beetween
-- input surface and the pipe. --
-- 3) give a path and two sections. The section
-- evoluate from First to Last Section.
--
-- 3) give a path and N sections. The section
-- evoluate from First to Last Section.
--
-- In general case the result is a NURBS. But we
-- can generate plane, cylindrical, spherical,
-- conical, toroidal surface in some particular case.
--
-- The natural parametrization of the result is:
--
-- U-Direction along the section.
-- V-Direction along the path.
--
-- But, in some particular case, the surface must
-- be construct otherwise.
-- The method "EchangeUV" return false in such cases.
--
uses
HCurve from Adaptor3d,
Curve from Geom,
Curve from Geom2d,
Surface from Geom,
Shape from GeomAbs,
SequenceOfCurve from TColGeom,
Trihedron from GeomFill,
LocationLaw from GeomFill,
SectionLaw from GeomFill,
Dir from gp
raises
ConstructionError from Standard
is
Create
returns Pipe from GeomFill;
---Purpose:
-- Constructs an empty algorithm for building pipes. Use
-- the function Init to initialize it.
Create ( Path : Curve from Geom;
Radius : Real from Standard)
returns Pipe from GeomFill;
Create ( Path : Curve from Geom;
FirstSect : Curve from Geom;
Option : Trihedron from GeomFill = GeomFill_IsCorrectedFrenet)
--- Purpose: Create a pipe with a constant section
-- (<FirstSection>) and a path (<Path>)
-- Option can be - GeomFill_IsCorrectedFrenet
-- - GeomFill_IsFrenet
-- - GeomFill_IsConstant
returns Pipe from GeomFill;
Create( Path : Curve from Geom2d;
Support: Surface from Geom;
FirstSect : Curve from Geom)
--- Purpose: Create a pipe with a constant section
-- (<FirstSection>) and a path defined by <Path> and <Support>
returns Pipe from GeomFill;
Create( Path : Curve from Geom;
FirstSect : Curve from Geom;
Dir : Dir from gp)
---Purpose: Create a pipe with a constant section
-- (<FirstSection>) and a path <Path> and a fixed
-- binormal direction <Dir>
returns Pipe from GeomFill;
Create( Path : Curve from Geom;
FirstSect : Curve from Geom;
LastSect : Curve from Geom )
---Purpose: Create a pipe with an evolving section
-- The section evoluate from First to Last Section
returns Pipe from GeomFill;
Create( Path : Curve from Geom;
NSections : SequenceOfCurve from TColGeom)
---Purpose: Create a pipe with N sections
-- The section evoluate from First to Last Section
returns Pipe from GeomFill;
Create( Path : Curve from Geom;
Curve1 : Curve from Geom;
Curve2 : Curve from Geom;
Radius : Real from Standard )
---Purpose: Create a pipe with a constant radius with 2
-- guide-line.
---Level : Advanced
returns Pipe from GeomFill;
Create( Path : HCurve from Adaptor3d;
Curve1 : HCurve from Adaptor3d;
Curve2 : HCurve from Adaptor3d;
Radius : Real from Standard )
---Purpose: Create a pipe with a constant radius with 2
-- guide-line.
---Level : Advanced
returns Pipe from GeomFill;
Create( Path : Curve from Geom;
Guide : HCurve from Adaptor3d;
FirstSect : Curve from Geom;
ByACR : Boolean from Standard;
rotat : Boolean from Standard)
---Purpose: Create a pipe with a constant section and with 1
-- guide-line.
-- Use the function Perform to build the surface.
-- All standard specific cases are detected in order to
-- construct, according to the respective geometric
-- nature of Path and the sections, a planar, cylindrical,
-- conical, spherical or toroidal surface, a surface of
-- linear extrusion or a surface of revolution.
-- In the general case, the result is a BSpline surface
-- (NURBS) built by approximation of a series of sections where:
-- - the number of sections N is chosen automatically
-- by the algorithm according to the respective
-- geometries of Path and the sections. N is greater than or equal to 2;
-- - N points Pi (with i in the range [ 1,N ]) are
-- defined at regular intervals along the curve Path
-- from its first point to its end point. At each point Pi,
-- a coordinate system Ti is computed with Pi as
-- origin, and with the tangential and normal vectors
-- to Path defining two of its coordinate axes.
-- In the case of a pipe with a constant circular section,
-- the first section is a circle of radius Radius centered
-- on the origin of Path and whose "Z Axis" is aligned
-- along the vector tangential to the origin of Path. In the
-- case of a pipe with a constant section, the first section
-- is the curve FirstSect. In these two cases, the ith
-- section (for values of i greater than 1) is obtained by
-- applying to a copy of this first section the geometric
-- transformation which transforms coordinate system
-- T1 into coordinate system Ti.
-- In the case of an evolving section, N-2 intermediate
-- curves Si are first computed (if N is greater than 2,
-- and with i in the range [ 2,N-1 ]) whose geometry
-- evolves regularly from the curve S1=FirstSect to the
-- curve SN=LastSect. The first section is FirstSect,
-- and the ith section (for values of i greater than 1) is
-- obtained by applying to the curve Si the geometric
-- transformation which transforms coordinate system
-- T1 into coordinate system Ti.
returns Pipe from GeomFill;
Init( me : in out)
is static private;
--
-- Init methods : The same options than in Create methods !
--
Init( me : in out;
Path : Curve from Geom;
Radius : Real from Standard)
is static;
Init( me : in out;
Path : Curve from Geom;
FirstSect : Curve from Geom;
Option : Trihedron from GeomFill
= GeomFill_IsCorrectedFrenet)
is static;
Init(me : in out;
Path : Curve from Geom2d;
Support: Surface from Geom;
FirstSect : Curve from Geom)
is static;
Init(me : in out;
Path : Curve from Geom;
FirstSect : Curve from Geom;
Dir : Dir from gp)
is static;
Init( me : in out;
Path : Curve from Geom;
FirstSect : Curve from Geom;
LastSect : Curve from Geom)
is static;
Init( me : in out;
Path : Curve from Geom;
NSections : SequenceOfCurve from TColGeom)
is static;
Init( me : in out;
Path : HCurve from Adaptor3d;
Curve1 : HCurve from Adaptor3d;
Curve2 : HCurve from Adaptor3d;
Radius : Real from Standard )
---Purpose: Create a pipe with a constant radius with 2
-- guide-line.
is static;
Init( me : in out;
Path : Curve from Geom;
Guide : HCurve from Adaptor3d;
FirstSect : Curve from Geom;
ByACR : Boolean from Standard;
rotat : Boolean from Standard )
is static;
---Purpose:
-- Initializes this pipe algorithm to build the following surface:
-- - a pipe with a constant circular section of radius
-- Radius along the path Path, or
-- - a pipe with constant section FirstSect along the path Path, or
-- - a pipe where the section evolves from FirstSect to
-- LastSect along the path Path.
-- Use the function Perform to build the surface.
-- Note: a description of the resulting surface is given under Constructors.
ApproxSurf(me : in out; WithParameters: Boolean from Standard)
---Purpose: The result (<mySurface>) is an approximation. Using
-- <SweepSectionGenerator> to do that. If
-- <WithParameters> is set to <Standard_True>, the
-- apprxoximation will be done in respect to the spine
-- parametrization.
is static private;
Perform( me : in out;
WithParameters: Boolean from Standard = Standard_False;
myPolynomial : Boolean from Standard = Standard_False)
---Purpose: Builds the pipe defined at the time of initialization of this
-- algorithm. A description of the resulting surface is given under Constructors.
-- If WithParameters (defaulted to false) is set to true, the
-- approximation algorithm (used only in the general case
-- of construction of a BSpline surface) builds the surface
-- with a u parameter corresponding to the one of the path.
-- Exceptions
-- Standard_ConstructionError if a surface cannot be constructed from the data.
-- Warning: It is the old Perform method, the next methode is recommended.
raises
ConstructionError from Standard
is static;
Perform(me : in out;
Tol : Real;
Polynomial : Boolean;
Conti : Shape from GeomAbs = GeomAbs_C1;
MaxDegree : Integer = 11;
NbMaxSegment : Integer = 30)
---Purpose: detects the particular cases. And compute the surface.
-- if none particular case is detected we make an approximation
-- with respect of the Tolerance <Tol>, the continuty <Conti>, the
-- maximum degree <MaxDegree>, the maximum number of span <NbMaxSegment>
-- and the spine parametrization.
raises
ConstructionError from Standard
---Purpose: If we can't create a surface with the data
is static;
KPartT4( me : in out)
returns Boolean is private;
Surface(me)
---C++: inline
---C++: return const &
---Purpose: Returns the surface built by this algorithm.
-- Warning
-- Do not use this function before the surface is built (in this
-- case the function will return a null handle).
returns Surface from Geom
is static;
ExchangeUV(me)
---Purpose: The u parametric direction of the surface constructed by
-- this algorithm usually corresponds to the evolution
-- along the path and the v parametric direction
-- corresponds to the evolution along the section(s).
-- However, this rule is not respected when constructing
-- certain specific Geom surfaces (typically cylindrical
-- surfaces, surfaces of revolution, etc.) for which the
-- parameterization is inversed.
-- The ExchangeUV function checks for this, and returns
-- true in all these specific cases.
-- Warning
-- Do not use this function before the surface is built.
returns Boolean from Standard
is static;
GenerateParticularCase(me: in out; B: Boolean from Standard)
---Purpose: Sets a flag to try to create as many planes,
-- cylinder,... as possible. Default value is
-- <Standard_False>.
---C++: inline
is static;
GenerateParticularCase(me)
---Purpose: Returns the flag.
---C++: inline
returns Boolean from Standard
is static;
ErrorOnSurf(me)
---Purpose: Returns the approximation's error. if the Surface
-- is plane, cylinder ... this error can be 0.
---C++: inline
returns Real from Standard
is static;
fields
myRadius : Real from Standard;
myError : Real from Standard;
myAdpPath : HCurve from Adaptor3d;
myAdpFirstSect : HCurve from Adaptor3d;
myAdpLastSect : HCurve from Adaptor3d;
mySurface : Surface from Geom;
myLoc : LocationLaw from GeomFill;
mySec : SectionLaw from GeomFill;
myType : Integer from Standard;
myExchUV : Boolean from Standard;
myKPart : Boolean from Standard;
myPolynomial : Boolean from Standard;
end Pipe;

1139
src/GeomFill/GeomFill_Pipe.cxx Executable file

File diff suppressed because it is too large Load Diff

56
src/GeomFill/GeomFill_Pipe.lxx Executable file
View File

@@ -0,0 +1,56 @@
// File: GeomFill_Pipe.lxx
// Created: Wed Apr 13 14:25:05 1994
// Author: Eric BONNARDEL
// <ebo@fuegox>
//=======================================================================
//function : const
//purpose :
//=======================================================================
inline const Handle(Geom_Surface)& GeomFill_Pipe::Surface() const
{
return mySurface;
}
//=======================================================================
//function : ExchangeUV
//purpose :
//=======================================================================
inline Standard_Boolean GeomFill_Pipe::ExchangeUV() const
{
return myExchUV;
}
//=======================================================================
//function : GenerateParticularCase
//purpose :
//=======================================================================
inline void GeomFill_Pipe::GenerateParticularCase(const Standard_Boolean B)
{
myKPart = B;
}
//=======================================================================
//function : GenerateParticularCase
//purpose :
//=======================================================================
inline Standard_Boolean GeomFill_Pipe::GenerateParticularCase() const
{
return myKPart;
}
//=======================================================================
//function : ErrorOnSurf
//purpose :
//=======================================================================
inline Standard_Real GeomFill_Pipe::ErrorOnSurf() const
{
return myError;
}

View File

@@ -0,0 +1,68 @@
-- File: GeomFill_PlanFunc.cdl
-- Created: Thu Oct 29 10:47:24 1998
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1998
private class PlanFunc from GeomFill
inherits FunctionWithDerivative from math
---Purpose:
uses
HCurve from Adaptor3d,
Pnt from gp,
Vec from gp,
XYZ from gp
is
Create(P : Pnt; V : Vec; C : HCurve from Adaptor3d)
returns PlanFunc from GeomFill;
Value(me: in out; X: Real; F: out Real)
---Purpose: computes the value <F>of the function for the variable <X>.
-- Returns True if the calculation were successfully done,
-- False otherwise.
returns Boolean
is redefined;
Derivative(me: in out; X: Real; D: out Real)
---Purpose: computes the derivative <D> of the function
-- for the variable <X>.
-- Returns True if the calculation were successfully done,
-- False otherwise.
returns Boolean
is redefined;
Values(me: in out; X: Real; F, D: out Real)
---Purpose: computes the value <F> and the derivative <D> of the
-- function for the variable <X>.
-- Returns True if the calculation were successfully done,
-- False otherwise.
returns Boolean
is redefined;
D2(me:in out; X:Real; F, D1, D2: out Real)
is static;
DEDT(me : in out; X:Real;
DP, DV : Vec;
DF : out Real)
is static;
D2E(me : in out; X:Real;
DP, D2P : Vec;
DV, D2V : Vec;
DFDT, D2FDT2, D2FDTDX : out Real)
is static;
fields
myPnt : XYZ;
myVec : XYZ;
V : XYZ;
G : Pnt;
myCurve : HCurve from Adaptor3d;
end PlanFunc;

View File

@@ -0,0 +1,96 @@
// File: GeomFill_PlanFunc.cxx
// Created: Thu Oct 29 12:00:47 1998
// Author: Philippe MANGIN
// <pmn@sgi29>
#include <GeomFill_PlanFunc.ixx>
GeomFill_PlanFunc::GeomFill_PlanFunc(const gp_Pnt& P,
const gp_Vec& V,
const Handle(Adaptor3d_HCurve)& C) :
myCurve(C)
{
myPnt = P.XYZ();
myVec = V.XYZ();
}
Standard_Boolean GeomFill_PlanFunc::Value(const Standard_Real X,
Standard_Real& F)
{
myCurve->D0(X, G);
V.SetLinearForm(-1, myPnt, G.XYZ());
F = myVec.Dot(V);
return Standard_True;
}
Standard_Boolean GeomFill_PlanFunc::Derivative(const Standard_Real X,
Standard_Real& D)
{
gp_Vec dg;
myCurve->D1(X, G, dg);
D = myVec.Dot(dg.XYZ());
return Standard_True;
}
Standard_Boolean GeomFill_PlanFunc::Values(const Standard_Real X,
Standard_Real& F,
Standard_Real& D)
{
gp_Vec dg;
myCurve->D1(X, G, dg);
V.SetLinearForm(-1, myPnt, G.XYZ());
F = myVec.Dot(V);
D = myVec.Dot(dg.XYZ());
return Standard_True;
}
//void GeomFill_PlanFunc::D2(const Standard_Real X,
// Standard_Real& F,
// Standard_Real& D1,
// Standard_Real& D2)
void GeomFill_PlanFunc::D2(const Standard_Real ,
Standard_Real& ,
Standard_Real& ,
Standard_Real& )
{
}
void GeomFill_PlanFunc::DEDT(const Standard_Real X,
const gp_Vec& DPnt,
const gp_Vec& DVec,
Standard_Real& DFDT)
{
myCurve->D0(X, G);
V.SetLinearForm(-1, myPnt, G.XYZ());
DFDT = DVec.Dot(V) - myVec.Dot(DPnt.XYZ());
}
void GeomFill_PlanFunc::D2E(const Standard_Real X,
const gp_Vec& DP,
// const gp_Vec& D2P,
const gp_Vec& ,
const gp_Vec& DV,
// const gp_Vec& D2V,
const gp_Vec& ,
Standard_Real& DFDT,
// Standard_Real& ,
Standard_Real& D2FDT2,
// Standard_Real& D2FDTDX)
Standard_Real& )
{
gp_Vec dg;
myCurve->D1(X, G, dg);
gp_XYZ DVDT;
V.SetLinearForm(-1, myPnt, G.XYZ());
DVDT.SetLinearForm(-1, DP.XYZ(), G.XYZ());
DFDT = DV.Dot(V) + myVec.Dot(DVDT);
}

View File

@@ -0,0 +1,72 @@
-- File: GeomFill_PolynomialConvertor.cdl
-- Created: Fri Jul 18 17:22:52 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
private class PolynomialConvertor from GeomFill
---Purpose: To convert circular section in polynome
uses
Matrix from math,
Pnt from gp,
Vec from gp,
Array1OfPnt from TColgp,
Array1OfVec from TColgp
raises NotDone from StdFail
is
Create returns PolynomialConvertor from GeomFill;
Initialized(me)
---Purpose: say if <me> is Initialized
returns Boolean;
Init(me: in out);
Section(me;
FirstPnt : Pnt from gp;
Center : Pnt from gp;
Dir : Vec from gp;
Angle : Real from Standard;
Poles : out Array1OfPnt from TColgp);
Section(me;
FirstPnt : Pnt from gp;
DFirstPnt : Vec from gp;
Center : Pnt from gp;
DCenter : Vec from gp;
Dir : Vec from gp;
DDir : Vec from gp;
Angle : Real from Standard;
DAngle : Real from Standard;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp);
Section(me;
FirstPnt : Pnt from gp;
DFirstPnt : Vec from gp;
D2FirstPnt: Vec from gp;
Center : Pnt from gp;
DCenter : Vec from gp;
D2Center : Vec from gp;
Dir : Vec from gp;
DDir : Vec from gp;
D2Dir : Vec from gp;
Angle : Real from Standard;
DAngle : Real from Standard;
D2Angle : Real from Standard;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
D2Poles : out Array1OfVec from TColgp);
fields
Ordre : Integer from Standard;
myinit : Boolean from Standard;
BH : Matrix from math;
end PolynomialConvertor;

View File

@@ -0,0 +1,358 @@
// File: GeomFill_PolynomialConvertor.cxx
// Created: Fri Jul 18 17:43:05 1997
// Author: Philippe MANGIN
// <pmn@sgi29>
#include <GeomFill_PolynomialConvertor.ixx>
#include <PLib.hxx>
#include <gp_Mat.hxx>
#include <Convert_CompPolynomialToPoles.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_HArray2OfReal.hxx>
#include <TColStd_HArray1OfInteger.hxx>
#include <TColStd_HArray1OfReal.hxx>
GeomFill_PolynomialConvertor::GeomFill_PolynomialConvertor():
Ordre(8),
myinit(Standard_False),
BH(1, Ordre, 1, Ordre)
{
}
Standard_Boolean GeomFill_PolynomialConvertor::Initialized() const
{
return myinit;
}
void GeomFill_PolynomialConvertor::Init()
{
if (myinit) return; //On n'initialise qu'une fois
Standard_Integer ii, jj;
Standard_Real terme;
math_Matrix H(1,Ordre, 1,Ordre), B(1,Ordre, 1,Ordre);
Handle(TColStd_HArray1OfReal)
Coeffs = new (TColStd_HArray1OfReal) (1, Ordre*Ordre),
TrueInter = new (TColStd_HArray1OfReal) (1,2);
Handle(TColStd_HArray2OfReal)
Poles1d = new (TColStd_HArray2OfReal) (1, Ordre, 1, Ordre),
Inter = new (TColStd_HArray2OfReal) (1,1,1,2);
//Calcul de B
Inter->SetValue(1, 1, -1);
Inter->SetValue(1, 2, 1);
TrueInter->SetValue(1, -1);
TrueInter->SetValue(2, 1);
Coeffs->Init(0);
for (ii=1; ii<=Ordre; ii++) { Coeffs->SetValue(ii+(ii-1)*Ordre, 1); }
//Convertion ancienne formules
Handle(TColStd_HArray1OfInteger) Ncf
= new (TColStd_HArray1OfInteger)(1,1);
Ncf->Init(Ordre);
Convert_CompPolynomialToPoles
AConverter(1, 1, 8, 8,
Ncf,
Coeffs,
Inter,
TrueInter);
/* Convert_CompPolynomialToPoles
AConverter(8, Ordre-1, Ordre-1,
Coeffs,
Inter,
TrueInter); En attente du bon Geomlite*/
AConverter.Poles(Poles1d);
for (jj=1; jj<=Ordre; jj++) {
for (ii=1; ii<=Ordre; ii++) {
terme = Poles1d->Value(ii,jj);
if (Abs(terme-1) < 1.e-9) terme = 1 ; //petite retouche
if (Abs(terme+1) < 1.e-9) terme = -1;
B(ii, jj) = terme;
}
}
//Calcul de H
myinit = PLib::HermiteCoefficients(-1, 1, Ordre/2-1, Ordre/2-1, H);
H.Transpose();
if (!myinit) return;
// reste l'essentiel
BH = B * H;
}
void GeomFill_PolynomialConvertor::Section(const gp_Pnt& FirstPnt,
const gp_Pnt& Center,
const gp_Vec& Dir,
const Standard_Real Angle,
TColgp_Array1OfPnt& Poles) const
{
math_Vector Vx(1, Ordre), Vy(1, Ordre);
math_Vector Px(1, Ordre), Py(1, Ordre);
Standard_Integer ii;
Standard_Real Cos_b = Cos(Angle), Sin_b = Sin(Angle);
Standard_Real beta, beta2, beta3;
gp_Vec V1(Center, FirstPnt), V2;
V2 = Dir^V1;
beta = Angle/2;
beta2 = beta * beta;
beta3 = beta * beta2;
// Calcul de la transformation
gp_Mat M(V1.X(), V2.X(), 0,
V1.Y(), V2.Y(), 0,
V1.Z(), V2.Z(), 0);
#ifdef DEB
Standard_Real r = FirstPnt.Distance(Center);
#else
FirstPnt.Distance(Center);
#endif
// Calcul des contraintes -----------
Vx(1) = 1; Vy(1) = 0;
Vx(2) = 0; Vy(2) = beta;
Vx(3) = -beta2; Vy(3) = 0;
Vx(4) = 0; Vy(4) = -beta3;
Vx(5) = Cos_b; Vy(5) = Sin_b;
Vx(6) = -beta*Sin_b; Vy(6) = beta*Cos_b;
Vx(7) = -beta2*Cos_b; Vy(7) = -beta2*Sin_b;
Vx(8) = beta3*Sin_b; Vy(8) = -beta3*Cos_b;
// Calcul des poles
Px = BH * Vx;
Py = BH * Vy;
gp_XYZ pnt;
for (ii=1; ii<=Ordre; ii++) {
pnt.SetCoord(Px(ii), Py(ii), 0);
pnt *= M;
pnt += Center.XYZ();
Poles(ii).ChangeCoord() = pnt;
}
}
void GeomFill_PolynomialConvertor::Section(const gp_Pnt& FirstPnt,
const gp_Vec& DFirstPnt,
const gp_Pnt& Center,
const gp_Vec& DCenter,
const gp_Vec& Dir,
const gp_Vec& DDir,
const Standard_Real Angle,
const Standard_Real DAngle,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfVec& DPoles) const
{
math_Vector Vx(1, Ordre), Vy(1, Ordre),
DVx(1, Ordre), DVy(1, Ordre);
math_Vector Px(1, Ordre), Py(1, Ordre),
DPx(1, Ordre), DPy(1, Ordre);
Standard_Integer ii;
Standard_Real Cos_b = Cos(Angle), Sin_b = Sin(Angle);
Standard_Real beta, beta2, beta3, bprim;
gp_Vec V1(Center, FirstPnt), V1Prim, V2;
V2 = Dir^V1;
beta = Angle/2;
bprim = DAngle/2;
beta2 = beta * beta;
beta3 = beta * beta2;
// Calcul des transformations
gp_Mat M (V1.X(), V2.X(), 0,
V1.Y(), V2.Y(), 0,
V1.Z(), V2.Z(), 0);
V1Prim = DFirstPnt - DCenter;
V2 = (DDir^V1) + (Dir^V1Prim);
gp_Mat MPrim (V1Prim.X(), V2.X(), 0,
V1Prim.Y(), V2.Y(), 0,
V1Prim.Z(), V2.Z(), 0);
// Calcul des contraintes -----------
Vx(1) = 1; Vy(1) = 0;
Vx(2) = 0; Vy(2) = beta;
Vx(3) = -beta2; Vy(3) = 0;
Vx(4) = 0; Vy(4) = -beta3;
Vx(5) = Cos_b; Vy(5) = Sin_b;
Vx(6) = -beta*Sin_b; Vy(6) = beta*Cos_b;
Vx(7) = -beta2*Cos_b; Vy(7) = -beta2*Sin_b;
Vx(8) = beta3*Sin_b; Vy(8) = -beta3*Cos_b;
Standard_Real b_bprim = bprim*beta,
b2_bprim = bprim*beta2;
DVx(1) = 0; DVy(1) = 0;
DVx(2) = 0; DVy(2) = bprim;
DVx(3) = -2*b_bprim; DVy(3) = 0;
DVx(4) = 0; DVy(4) = -3*b2_bprim;
DVx(5) = -2*bprim*Sin_b; DVy(5) = 2*bprim*Cos_b;
DVx(6) = -bprim*Sin_b - 2*b_bprim*Cos_b;
DVy(6) = bprim*Cos_b - 2*b_bprim*Sin_b;
DVx(7) = 2*b_bprim*(-Cos_b + beta*Sin_b);
DVy(7) = -2*b_bprim*(Sin_b+beta*Cos_b);
DVx(8) = b2_bprim*(3*Sin_b + 2*beta*Cos_b);
DVy(8) = b2_bprim*(2*beta*Sin_b - 3*Cos_b);
// Calcul des poles
Px = BH * Vx;
Py = BH * Vy;
DPx = BH * DVx;
DPy = BH * DVy;
gp_XYZ P, DP, aux;
for (ii=1; ii<=Ordre; ii++) {
P.SetCoord(Px(ii), Py(ii), 0);
Poles(ii).ChangeCoord() = M*P + Center.XYZ();
P *= MPrim;
DP.SetCoord(DPx(ii), DPy(ii), 0);
DP *= M;
aux.SetLinearForm(1, P, 1, DP, DCenter.XYZ());
DPoles(ii).SetXYZ(aux);
}
}
void GeomFill_PolynomialConvertor::Section(const gp_Pnt& FirstPnt,
const gp_Vec& DFirstPnt,
const gp_Vec& D2FirstPnt,
const gp_Pnt& Center,
const gp_Vec& DCenter,
const gp_Vec& D2Center,
const gp_Vec& Dir,
const gp_Vec& DDir,
const gp_Vec& D2Dir,
const Standard_Real Angle,
const Standard_Real DAngle,
const Standard_Real D2Angle,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfVec& DPoles,
TColgp_Array1OfVec& D2Poles) const
{
math_Vector Vx(1, Ordre), Vy(1, Ordre),
DVx(1, Ordre), DVy(1, Ordre),
D2Vx(1, Ordre), D2Vy(1, Ordre);
math_Vector Px(1, Ordre), Py(1, Ordre),
DPx(1, Ordre), DPy(1, Ordre),
D2Px(1, Ordre), D2Py(1, Ordre);
Standard_Integer ii;
Standard_Real aux, Cos_b = Cos(Angle), Sin_b = Sin(Angle);
Standard_Real beta, beta2, beta3, bprim, bprim2, bsecn;
gp_Vec V1(Center, FirstPnt), V1Prim, V1Secn, V2;
V2 = Dir^V1;
beta = Angle/2;
bprim = DAngle/2;
bsecn = D2Angle/2;
bsecn = D2Angle/2;
beta2 = beta * beta;
beta3 = beta * beta2;
bprim2 = bprim*bprim;
// Calcul des transformations
gp_Mat M (V1.X(), V2.X(), 0,
V1.Y(), V2.Y(), 0,
V1.Z(), V2.Z(), 0);
V1Prim = DFirstPnt - DCenter;
V2 = (DDir^V1) + (Dir^V1Prim);
gp_Mat MPrim (V1Prim.X(), V2.X(), 0,
V1Prim.Y(), V2.Y(), 0,
V1Prim.Z(), V2.Z(), 0);
V1Secn = D2FirstPnt - D2Center;
V2 = DDir^V1Prim;
V2 *= 2;
V2 += (D2Dir^V1) + (Dir^V1Secn);
gp_Mat MSecn (V1Secn.X(), V2.X(), 0,
V1Secn.Y(), V2.Y(), 0,
V1Secn.Z(), V2.Z(), 0);
// Calcul des contraintes -----------
Vx(1) = 1; Vy(1) = 0;
Vx(2) = 0; Vy(2) = beta;
Vx(3) = -beta2; Vy(3) = 0;
Vx(4) = 0; Vy(4) = -beta3;
Vx(5) = Cos_b; Vy(5) = Sin_b;
Vx(6) = -beta*Sin_b; Vy(6) = beta*Cos_b;
Vx(7) = -beta2*Cos_b; Vy(7) = -beta2*Sin_b;
Vx(8) = beta3*Sin_b; Vy(8) = -beta3*Cos_b;
Standard_Real b_bprim = bprim*beta,
b2_bprim = bprim*beta2,
b_bsecn = bsecn*beta;
DVx(1) = 0; DVy(1) = 0;
DVx(2) = 0; DVy(2) = bprim;
DVx(3) = -2*b_bprim; DVy(3) = 0;
DVx(4) = 0; DVy(4) = -3*b2_bprim;
DVx(5) = -2*bprim*Sin_b; DVy(5) = 2*bprim*Cos_b;
DVx(6) = -bprim*Sin_b - 2*b_bprim*Cos_b;
DVy(6) = bprim*Cos_b - 2*b_bprim*Sin_b;
DVx(7) = 2*b_bprim*(-Cos_b + beta*Sin_b);
DVy(7) = -2*b_bprim*(Sin_b + beta*Cos_b);
DVx(8) = b2_bprim*(3*Sin_b + 2*beta*Cos_b);
DVy(8) = b2_bprim*(2*beta*Sin_b - 3*Cos_b);
D2Vx(1) = 0; D2Vy(1) = 0;
D2Vx(2) = 0; D2Vy(2) = bsecn;
D2Vx(3) = -2*(bprim2+b_bsecn); D2Vy(3) = 0;
D2Vx(4) = 0; D2Vy(4) = -3*beta*(2*bprim2+b_bsecn);
D2Vx(5) = -2*(bsecn*Sin_b + 2*bprim2*Cos_b);
D2Vy(5) = 2*(bsecn*Cos_b - 2*bprim2*Sin_b);
D2Vx(6) = (4*beta*bprim2-bsecn)*Sin_b - 2*(2*bprim2+b_bsecn)*Cos_b;
D2Vy(6) = (bsecn - 4*beta*bprim2)*Cos_b
- 2*(b_bsecn + 2*bprim2)*Sin_b;
aux = 2*(bprim2+b_bsecn);
D2Vx(7) = aux*(-Cos_b + beta*Sin_b)
+ 2*beta*bprim2*(2*beta*Cos_b + 3*Sin_b);
D2Vy(7) = -aux*(Sin_b + beta*Cos_b)
- 2*beta*bprim2*(3*Cos_b - 2*beta*Sin_b);
aux = beta*(2*bprim2+b_bsecn);
D2Vx(8) = aux * (3*Sin_b + 2*beta*Cos_b)
+ 4*beta2*bprim2 * (2*Cos_b - beta*Sin_b);
D2Vy(8)= aux * (2*beta*Sin_b - 3*Cos_b)
+ 4*beta2*bprim2 * (2*Sin_b + beta*Cos_b);
// Calcul des poles
Px = BH * Vx;
Py = BH * Vy;
DPx = BH * DVx;
DPy = BH * DVy;
D2Px = BH * D2Vx;
D2Py = BH * D2Vy;
gp_XYZ P, DP, D2P, auxyz;
for (ii=1; ii<=Ordre; ii++) {
P.SetCoord(Px(ii), Py(ii), 0);
DP.SetCoord(DPx(ii), DPy(ii), 0);
D2P.SetCoord(D2Px(ii), D2Py(ii), 0);
Poles(ii).ChangeCoord() = M*P + Center.XYZ();
auxyz.SetLinearForm(1, MPrim*P,
1, M*DP,
DCenter.XYZ());
DPoles(ii).SetXYZ(auxyz);
P *= MSecn;
DP *= MPrim;
D2P*= M;
auxyz.SetLinearForm(1, P,
2, DP,
1, D2P,
D2Center.XYZ());
D2Poles(ii).SetXYZ(auxyz);
}
}

View File

@@ -0,0 +1,118 @@
-- File: GeomFill_Profiler.cdl
-- Created: Thu Feb 17 10:44:36 1994
-- Author: Bruno DUMORTIER
-- <dub@fuegox>
---Copyright: Matra Datavision 1994
class Profiler from GeomFill
---Purpose: Evaluation of the common BSplineProfile of a group
-- of curves from Geom. All the curves will have the
-- same degree, the same knot-vector, so the same
-- number of poles.
uses
Array1OfReal from TColStd,
Array1OfInteger from TColStd,
Array1OfPnt from TColgp,
Curve from Geom,
SequenceOfCurve from TColGeom
raises
NotDone from StdFail,
DomainError from Standard
is
Create returns Profiler from GeomFill;
Delete(me:out) is virtual;
---C++: alias "Standard_EXPORT virtual ~GeomFill_Profiler(){Delete() ; }"
AddCurve( me : in out;
Curve : in Curve from Geom)
is static;
Perform(me : in out ;
PTol : in Real from Standard)
---Purpose: Converts all curves to BSplineCurves.
-- Set them to the common profile.
-- <PTol> is used to compare 2 knots.
is virtual;
Degree(me) returns Integer from Standard
raises
NotDone from StdFail
---Purpose: Raises if not yet perform
is static;
IsPeriodic(me) returns Boolean from Standard
---C++: inline
is static;
NbPoles(me) returns Integer from Standard
raises
NotDone from StdFail
---Purpose: Raises if not yet perform
is static;
Poles(me; Index : in Integer from Standard;
Poles : in out Array1OfPnt from TColgp)
---Purpose: returns in <Poles> the poles of the BSplineCurve
-- from index <Index> adjusting to the current profile.
raises
NotDone from StdFail,
---Purpose: Raises if not yet perform
DomainError from Standard
---Purpose: Raises if <Index> not in the range [1,NbCurves]
-- if the length of <Poles> is not equal to
-- NbPoles().
is static;
Weights(me; Index : in Integer from Standard;
Weights : in out Array1OfReal from TColStd)
---Purpose: returns in <Weights> the weights of the BSplineCurve
-- from index <Index> adjusting to the current profile.
raises
NotDone from StdFail,
---Purpose: Raises if not yet perform
DomainError from Standard
---Purpose: Raises if <Index> not in the range [1,NbCurves] or
-- if the length of <Weights> is not equal to
-- NbPoles().
is static;
NbKnots(me) returns Integer from Standard
raises
NotDone from StdFail
---Purpose: Raises if not yet perform
is static;
KnotsAndMults(me;
Knots : in out Array1OfReal from TColStd;
Mults : in out Array1OfInteger from TColStd)
raises
NotDone from StdFail,
---Purpose: Raises if not yet perform
DomainError from Standard
---Purpose: Raises if the lengthes of <Knots> and <Mults> are
-- not equal to NbKnots().
is static;
Curve(me; Index : Integer from Standard)
returns Curve from Geom
---C++: return const&
---C++: inline
is static;
fields
mySequence : SequenceOfCurve from TColGeom is protected;
myIsDone : Boolean from Standard is protected;
myIsPeriodic : Boolean from Standard is protected;
end Profiler;

View File

@@ -0,0 +1,289 @@
// File: GeomFill_Profiler.cxx
// Created: Thu Feb 17 11:33:12 1994
// Author: Bruno DUMORTIER
// <dub@fuegox>
#include <GeomFill_Profiler.ixx>
#include <GeomConvert.hxx>
#include <BSplCLib.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Geom_Conic.hxx>
#include <GeomConvert_ApproxCurve.hxx>
//=======================================================================
//function : GeomFill_Profiler
//purpose :
//=======================================================================
GeomFill_Profiler::GeomFill_Profiler()
{
myIsDone = Standard_False;
myIsPeriodic = Standard_True;
}
//=======================================================================
void GeomFill_Profiler::Delete()
{}
//=======================================================================
//function : AddCurve
//purpose :
//=======================================================================
void GeomFill_Profiler::AddCurve(const Handle(Geom_Curve)& Curve)
{
Handle(Geom_Curve) C;
//// modified by jgv, 19.01.05 for OCC7354 ////
Handle(Geom_Curve) theCurve = Curve;
if (theCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
theCurve = (*((Handle(Geom_TrimmedCurve)*)&theCurve))->BasisCurve();
if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
{
GeomConvert_ApproxCurve appr(Curve, Precision::Confusion(), GeomAbs_C1, 16, 14);
if (appr.HasResult())
C = appr.Curve();
}
if (C.IsNull())
C = GeomConvert::CurveToBSplineCurve(Curve);
/*
if ( Curve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
C = Handle(Geom_Curve)::DownCast(Curve->Copy());
}
else {
C = GeomConvert::CurveToBSplineCurve(Curve,Convert_QuasiAngular);
}
*/
///////////////////////////////////////////////
mySequence.Append( C);
if ( myIsPeriodic && !C->IsPeriodic())
myIsPeriodic = Standard_False;
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void GeomFill_Profiler::Perform(const Standard_Real PTol)
{
Standard_Integer i;
// Standard_Integer myDegree = 0, myNbPoles = 0;
Standard_Integer myDegree = 0;
Handle(Geom_BSplineCurve) C;
Standard_Real U1, U2, UFirst=0, ULast=0;
Standard_Real EcartMax = 0.;
for ( i = 1; i <= mySequence.Length(); i++) {
C = Handle(Geom_BSplineCurve)::DownCast(mySequence(i));
// si non periodique, il faut deperiodiser toutes les courbes
// on les segmente ensuite pour assurer K(1) et K(n) de multiplicite
// degre + 1
U2 = C->Knot(C->LastUKnotIndex());
U1 = C->Knot(C->FirstUKnotIndex());
if ( !myIsPeriodic && C->IsPeriodic()) {
C->SetNotPeriodic();
C->Segment( U1, U2);
}
// evaluate the max degree
myDegree = Max( myDegree, C->Degree());
// Calcul de Max ( Ufin - Udeb) sur l ensemble des courbes.
if ( ( U2 - U1) > EcartMax) {
EcartMax = U2 - U1;
UFirst = U1;
ULast = U2;
}
}
// increase the degree of the curves to my degree
// reparametrize them in the range U1, U2.
for ( i = 1; i <= mySequence.Length(); i++) {
C = Handle(Geom_BSplineCurve)::DownCast(mySequence(i));
C->IncreaseDegree( myDegree);
TColStd_Array1OfReal Knots(1,C->NbKnots());
C->Knots(Knots);
BSplCLib::Reparametrize(UFirst,ULast,Knots);
C->SetKnots(Knots);
}
// inserting in the first curve the knot-vector of all the others.
C = Handle(Geom_BSplineCurve)::DownCast(mySequence(1));
for ( i = 2; i <= mySequence.Length(); i++) {
Handle(Geom_BSplineCurve) Ci =
Handle(Geom_BSplineCurve)::DownCast(mySequence(i));
TColStd_Array1OfReal Ki(1,Ci->NbKnots());
Ci->Knots(Ki);
TColStd_Array1OfInteger Mi(1,Ci->NbKnots());
Ci->Multiplicities(Mi);
C->InsertKnots( Ki, Mi, PTol, Standard_False);
}
TColStd_Array1OfReal NewKnots(1,C->NbKnots());
C->Knots(NewKnots);
TColStd_Array1OfInteger NewMults(1,C->NbKnots());
C->Multiplicities(NewMults);
for ( i = 2; i <= mySequence.Length(); i++) {
Handle(Geom_BSplineCurve) Ci =
Handle(Geom_BSplineCurve)::DownCast(mySequence(i));
Ci->InsertKnots(NewKnots, NewMults, PTol, Standard_False);
}
// essai : tentative mise des poids sur chaque section a une moyenne 1
for ( i = 1; i <= mySequence.Length(); i++) {
Handle(Geom_BSplineCurve) Ci =
Handle(Geom_BSplineCurve)::DownCast(mySequence(i));
if ( Ci->IsRational() ) {
Standard_Integer np = Ci->NbPoles();
Standard_Real sigma = 0.;
Standard_Integer j;
for ( j = 1; j <= np; j++) {
sigma += Ci->Weight(j);
}
sigma /= np;
for ( j= 1; j<= np; j++) {
Ci->SetWeight(j,Ci->Weight(j) / sigma);
}
}
}
// fin de l essai
myIsDone = Standard_True;
}
//=======================================================================
//function : Degree
//purpose :
//=======================================================================
Standard_Integer GeomFill_Profiler::Degree() const
{
if ( !myIsDone)
StdFail_NotDone::Raise("GeomFill_Profiler::Degree");
Handle(Geom_BSplineCurve) C =
Handle(Geom_BSplineCurve)::DownCast(mySequence(1));
return C->Degree();
}
//=======================================================================
//function : NbPoles
//purpose :
//=======================================================================
Standard_Integer GeomFill_Profiler::NbPoles() const
{
if ( !myIsDone)
StdFail_NotDone::Raise("GeomFill_Profiler::Degree");
Handle(Geom_BSplineCurve) C =
Handle(Geom_BSplineCurve)::DownCast(mySequence(1));
return C->NbPoles();
}
//=======================================================================
//function : Poles
//purpose :
//=======================================================================
void GeomFill_Profiler::Poles(const Standard_Integer Index,
TColgp_Array1OfPnt& Poles) const
{
if ( !myIsDone)
StdFail_NotDone::Raise("GeomFill_Profiler::Degree");
Standard_DomainError_Raise_if( Poles.Length() != NbPoles(),
"GeomFill_Profiler::Poles");
Standard_DomainError_Raise_if( Index < 1 || Index > mySequence.Length(),
"GeomFill_Profiler::Poles");
Handle(Geom_BSplineCurve) C =
Handle(Geom_BSplineCurve)::DownCast(mySequence(Index));
C->Poles(Poles);
}
//=======================================================================
//function : Weights
//purpose :
//=======================================================================
void GeomFill_Profiler::Weights(const Standard_Integer Index,
TColStd_Array1OfReal& Weights) const
{
if ( !myIsDone)
StdFail_NotDone::Raise("GeomFill_Profiler::Degree");
Standard_DomainError_Raise_if( Weights.Length() != NbPoles(),
"GeomFill_Profiler::Weights");
Standard_DomainError_Raise_if( Index < 1 || Index > mySequence.Length(),
"GeomFill_Profiler::Weights");
Handle(Geom_BSplineCurve) C =
Handle(Geom_BSplineCurve)::DownCast(mySequence(Index));
C->Weights(Weights);
}
//=======================================================================
//function : NbKnots
//purpose :
//=======================================================================
Standard_Integer GeomFill_Profiler::NbKnots() const
{
if ( !myIsDone)
StdFail_NotDone::Raise("GeomFill_Profiler::Degree");
Handle(Geom_BSplineCurve) C =
Handle(Geom_BSplineCurve)::DownCast(mySequence(1));
return C->NbKnots();
}
//=======================================================================
//function : KnotsAndMults
//purpose :
//=======================================================================
void GeomFill_Profiler::KnotsAndMults(TColStd_Array1OfReal& Knots,
TColStd_Array1OfInteger& Mults ) const
{
if ( !myIsDone)
StdFail_NotDone::Raise("GeomFill_Profiler::Degree");
#ifndef No_Exception
Standard_Integer n = NbKnots();
#endif
Standard_DomainError_Raise_if( Knots.Length() != n || Mults.Length() != n,
"GeomFill_Profiler::KnotsAndMults");
Handle(Geom_BSplineCurve) C =
Handle(Geom_BSplineCurve)::DownCast(mySequence(1));
C->Knots(Knots);
C->Multiplicities(Mults);
}

View File

@@ -0,0 +1,27 @@
// File: GeomFill_Profiler.lxx
// Created: Fri Feb 18 14:08:53 1994
// Author: Bruno DUMORTIER
// <dub@fuegox>
//=======================================================================
//function : IsPeriodic
//purpose :
//=======================================================================
inline Standard_Boolean GeomFill_Profiler::IsPeriodic() const
{
return myIsPeriodic;
}
//=======================================================================
//function : Curve
//purpose :
//=======================================================================
inline const Handle(Geom_Curve)& GeomFill_Profiler::Curve
(const Standard_Integer Index) const
{
return mySequence( Index);
}

View File

@@ -0,0 +1,79 @@
-- File: GeomFill_QuasiAngularConvertor.cdl
-- Created: Wed Aug 6 09:28:30 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
private class QuasiAngularConvertor from GeomFill
---Purpose: To convert circular section in QuasiAngular Bezier
-- form
uses
Matrix from math,
Vector from math,
Pnt from gp,
Vec from gp,
Array1OfReal from TColStd,
Array1OfPnt from TColgp,
Array1OfVec from TColgp
raises NotDone from StdFail
is
Create returns QuasiAngularConvertor from GeomFill;
Initialized(me)
---Purpose: say if <me> is Initialized
returns Boolean;
Init(me: in out);
Section(me : in out;
FirstPnt : Pnt from gp;
Center : Pnt from gp;
Dir : Vec from gp;
Angle : Real from Standard;
Poles : out Array1OfPnt from TColgp;
Weights : out Array1OfReal from TColStd);
Section(me: in out;
FirstPnt : Pnt from gp;
DFirstPnt : Vec from gp;
Center : Pnt from gp;
DCenter : Vec from gp;
Dir : Vec from gp;
DDir : Vec from gp;
Angle : Real from Standard;
DAngle : Real from Standard;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
Weights : out Array1OfReal from TColStd;
DWeights : out Array1OfReal from TColStd);
Section(me : in out;
FirstPnt : Pnt from gp;
DFirstPnt : Vec from gp;
D2FirstPnt: Vec from gp;
Center : Pnt from gp;
DCenter : Vec from gp;
D2Center : Vec from gp;
Dir : Vec from gp;
DDir : Vec from gp;
D2Dir : Vec from gp;
Angle : Real from Standard;
DAngle : Real from Standard;
D2Angle : Real from Standard;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
D2Poles : out Array1OfVec from TColgp;
Weights : out Array1OfReal from TColStd;
DWeights : out Array1OfReal from TColStd;
D2Weights : out Array1OfReal from TColStd);
fields
myinit : Boolean from Standard;
B : Matrix from math;
Px, Py, W, Vx, Vy, Vw : Vector from math;
end QuasiAngularConvertor;

View File

@@ -0,0 +1,593 @@
// File: GeomFill_QuasiAngularConvertor.cxx
// Created: Wed Aug 6 09:31:38 1997
// Author: Philippe MANGIN
// <pmn@sgi29>
#include <GeomFill_QuasiAngularConvertor.ixx>
#include <PLib.hxx>
#include <gp_Mat.hxx>
#include <gp_Ax1.hxx>
#include <Convert_CompPolynomialToPoles.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_HArray2OfReal.hxx>
#include <TColStd_HArray1OfInteger.hxx>
#include <TColStd_HArray1OfReal.hxx>
#define NullAngle 1.e-6
// QuasiAngular is rational definition of Cos(theta(t) and sin(theta)
// on [-alpha, +alpha] with
// 2 2
// U - V
// cos (theta(t)) = ----------
// 2 2
// U + V
//
// 2 * U*V
// sin (theta(t)) = ----------
// 2 2
// U + V
// 3
// V(t) = t + c t
// 2
// U(t) = 1 + b t
// 1
// c = --- + b
// 3
//
//
// -1 gamma
// b =--------- + -----------------------
// 2
// gamma 3*(tang gamma - gamma)
//
// with gamma = alpha / 2
GeomFill_QuasiAngularConvertor::GeomFill_QuasiAngularConvertor():
myinit(Standard_False),
B(1, 7, 1, 7),
Px(1, 7), Py(1, 7),
W(1,7), Vx(1, 7), Vy(1, 7), Vw(1,7)
{
}
Standard_Boolean GeomFill_QuasiAngularConvertor::Initialized() const
{
return myinit;
}
void GeomFill_QuasiAngularConvertor::Init()
{
if (myinit) return; //On n'initialise qu'une fois
Standard_Integer ii, jj, Ordre=7;
Standard_Real terme;
TColStd_Array1OfReal Coeffs(1, Ordre*Ordre), TrueInter(1,2), Inter(1,2);
Handle(TColStd_HArray2OfReal)
Poles1d = new (TColStd_HArray2OfReal) (1, Ordre, 1, Ordre);
//Calcul de B
Inter.SetValue(1, -1);
Inter.SetValue(2, 1);
TrueInter.SetValue(1, -1);
TrueInter.SetValue(2, 1);
Coeffs.Init(0);
for (ii=1; ii<=Ordre; ii++) { Coeffs.SetValue(ii+(ii-1)*Ordre, 1); }
//Convertion
Convert_CompPolynomialToPoles
AConverter(Ordre, Ordre-1, Ordre-1,
Coeffs,
Inter,
TrueInter);
AConverter.Poles(Poles1d);
for (jj=1; jj<=Ordre; jj++) {
for (ii=1; ii<=Ordre; ii++) {
terme = Poles1d->Value(ii,jj);
if (Abs(terme-1) < 1.e-9) terme = 1 ; //petite retouche
if (Abs(terme+1) < 1.e-9) terme = -1;
B(ii, jj) = terme;
}
}
// Init des polynomes
Vx.Init(0);
Vx(1) = 1;
Vy.Init(0);
Vy(2) = 2;
Vw.Init(0);
Vw(1) = 1;
myinit = Standard_True;
}
void GeomFill_QuasiAngularConvertor::Section(const gp_Pnt& FirstPnt,
const gp_Pnt& Center,
const gp_Vec& Dir,
const Standard_Real Angle,
TColgp_Array1OfPnt& Poles,
TColStd_Array1OfReal& Weights)
{
Standard_Real b, b2, c, c2,tan_b;
Standard_Integer ii;
Standard_Real beta, beta2, beta3, beta4, beta5, beta6, wi;
gp_XYZ aux;
gp_Mat Rot;
// Calcul de la transformation
gp_Vec V1(Center, FirstPnt), V2;
Rot.SetRotation(Dir.XYZ(), Angle/2);
aux = V1.XYZ();
aux *= Rot;
V1.SetXYZ(aux);
V2 = Dir^V1;
gp_Mat M(V1.X(), V2.X(), 0,
V1.Y(), V2.Y(), 0,
V1.Z(), V2.Z(), 0);
#ifdef DEB
Standard_Real r = FirstPnt.Distance(Center);
#else
FirstPnt.Distance(Center);
#endif
// Calcul des coeffs -----------
beta = Angle/4;
beta2 = beta * beta;
beta3 = beta * beta2;
beta4 = beta2*beta2;
beta5 = beta3*beta2;
beta6 = beta3*beta3;
if ((PI/2 - beta)> NullAngle) {
if (Abs(beta) < NullAngle) {
Standard_Real cf = 2.0/(3*5*7);
b = - (0.2+cf*beta2) / (1+ 0.2*beta2);
// b = beta5 / cf;
}
else {
tan_b = Tan(beta);
b = - 1.0e0 / beta2;
b += beta / (3*(tan_b - beta));
}
}
else b = ((Standard_Real) -1)/beta2;
c = ((Standard_Real) 1)/ 3 + b;
b2 = b*b;
c2 = c*c;
// X = U*U - V*V
Vx(3) = beta2*(2*b - 1);
Vx(5) = beta4*(b2 - 2*c);
Vx(7) = -beta6*c2;
//Y = 2*U*V
Vy(2) = 2*beta;
Vy(4) = beta3*2*(c+b);
Vy(6) = 2*beta5*b*c;
// W = U*U + V*V
Vw(3) = beta2*(1 + 2*b);
Vw(5) = beta4*(2*c + b2);
Vw(7) = beta6*c2;
// Calculs des poles
Px.Multiply(B, Vx);
Py.Multiply(B, Vy);
W.Multiply(B, Vw);
// Transfo
gp_XYZ pnt;
for (ii=1; ii<=7; ii++) {
wi = W(ii);
pnt.SetCoord(Px(ii)/wi, Py(ii)/wi, 0);
pnt *= M;
pnt += Center.XYZ();
Poles(ii).ChangeCoord() = pnt;
Weights(ii) = wi;
}
}
void GeomFill_QuasiAngularConvertor::Section(const gp_Pnt& FirstPnt,
const gp_Vec& DFirstPnt,
const gp_Pnt& Center,
const gp_Vec& DCenter,
const gp_Vec& Dir,
const gp_Vec& DDir,
const Standard_Real Angle,
const Standard_Real DAngle,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfVec& DPoles,
TColStd_Array1OfReal& Weights,
TColStd_Array1OfReal& DWeights)
{
Standard_Integer Ordre = 7;
math_Vector DVx(1, Ordre), DVy(1, Ordre), DVw(1, Ordre),
DPx(1, Ordre), DPy(1, Ordre), DW(1, Ordre);
Standard_Real b, b2, c, c2,tan_b;
Standard_Real bpr, dtan_b;
Standard_Integer ii;
Standard_Real beta, beta2, beta3, beta4, beta5, beta6, betaprim;
gp_Vec V1(Center, FirstPnt), V1Prim, V2;
// Calcul des transformations
gp_XYZ aux;
Standard_Real Sina, Cosa;
gp_Mat Rot, RotPrim, D, DPrim;
// La rotation s'ecrit I + sin(Ang) * D + (1. - cos(Ang)) * D*D
// ou D est l'application x -> Dir ^ x
Rot.SetRotation(Dir.XYZ(), Angle/2);
// La derive s'ecrit donc :
// AngPrim * (sin(Ang)*D*D + cos(Ang)*D)
// + sin(Ang)*DPrim + (1. - cos(Ang)) *(DPrim*D + D*DPrim)
Sina = Sin(Angle/2);
Cosa = Cos(Angle/2);
D.SetCross(Dir.XYZ());
DPrim.SetCross(DDir.XYZ());
RotPrim = (D.Powered(2)).Multiplied(Sina);
RotPrim += D.Multiplied(Cosa);
RotPrim *= DAngle/2;
RotPrim += DPrim.Multiplied(Sina);
RotPrim += ((DPrim.Multiplied(D)).Added(D.Multiplied(DPrim))).Multiplied(1-Cosa);
aux = (DFirstPnt - DCenter).XYZ().Multiplied(Rot);
aux += V1.XYZ().Multiplied(RotPrim);
V1Prim.SetXYZ(aux);
aux = V1.XYZ();
aux.Multiply(Rot);
V1.SetXYZ(aux);
V2 = Dir^V1;
gp_Mat M (V1.X(), V2.X(), 0,
V1.Y(), V2.Y(), 0,
V1.Z(), V2.Z(), 0);
V2 = (DDir.Crossed(V1)).Added(Dir.Crossed(V1Prim));
gp_Mat MPrim (V1Prim.X(), V2.X(), 0,
V1Prim.Y(), V2.Y(), 0,
V1Prim.Z(), V2.Z(), 0);
// Calcul des constante -----------
beta = Angle/4;
betaprim = DAngle/4;
beta2 = beta * beta;
beta3 = beta * beta2;
beta4 = beta2*beta2;
beta5 = beta3*beta2;
beta6 = beta3*beta3;
if (Abs(beta) < NullAngle) {
// On calcul b par D.L
Standard_Real cf = 2.0/(3*5*7);
Standard_Real Num, Denom;
Num = 0.2 + cf*beta2;
Denom = 1+0.2*beta2;
b = - Num/Denom;
bpr = -2*beta*betaprim*(cf*Denom - 0.2*Num)/(Denom*Denom);
}
else {
b = ((Standard_Real) -1)/beta2;
bpr = (2*betaprim) / beta3;
if ((PI/2 - beta)> NullAngle) {
tan_b = Tan(beta);
dtan_b = betaprim * (1 + tan_b*tan_b);
b2 = tan_b - beta;
b += beta / (3*b2);
bpr += (betaprim*tan_b - beta*dtan_b) / (3*b2*b2);
}
}
c = ((Standard_Real) 1)/ 3 + b;
b2 = b*b;
c2 = c*c;
// X = U*U - V*V
Vx(3) = beta2*(2*b - 1);
Vx(5) = beta4*(b2 - 2*c);
Vx(7) = -beta6*c2;
DVx.Init(0);
DVx(3) = 2*(beta*betaprim*(2*b - 1) + bpr*beta2);
DVx(5) = 4*beta3*betaprim*(b2 - 2*c) + 2*beta4*bpr*(b-1);
DVx(7) = - 6*beta5*betaprim*c2 - 2*beta6*bpr*c;
//Y = 2*U*V
Vy(2) = 2*beta;
Vy(4) = beta3*2*(c+b);
Vy(6) = 2*beta5*b*c;
DVy.Init(0);
DVy(2) = 2*betaprim;
DVy(4) = 6*beta2*betaprim*(b+c) + 4*beta3*bpr;
DVy(6) = 10*beta4*betaprim*b*c + 2*beta5*bpr*(b+c);
// W = U*U + V*V
Vw(3) = beta2*(1 + 2*b);
Vw(5) = beta4*(2*c + b2);
Vw(7) = beta6*c2;
DVw.Init(0);
// DVw(3) = 2*(beta*betaprim*(1 + 2*b) + beta2*bpr);
DVw(3) = 2*beta*(betaprim*(1 + 2*b) + beta*bpr);
// DVw(5) = 4*beta3*betaprim*(2*c + b2) + 2*beta4*bpr*(b+1);
DVw(5) = 2*beta3*(2*betaprim*(2*c + b2) + beta*bpr*(b+1));
// DVw(7) = 6*beta5*betaprim*c2 + 2*beta6*bpr*c;
DVw(7) = 2*beta5*c*(3*betaprim*c + beta*bpr);
// Calcul des poles
Px.Multiply(B, Vx);
Py.Multiply(B, Vy);
W.Multiply(B, Vw);
DPx.Multiply(B, DVx);
DPy.Multiply(B, DVy);
DW.Multiply(B, DVw);
gp_XYZ P, DP;
Standard_Real wi;
for (ii=1; ii<=Ordre; ii++) {
wi = W(ii);
P.SetCoord(Px(ii)/wi, Py(ii)/wi, 0);
DP.SetCoord(DPx(ii)/wi, DPy(ii)/wi, 0);
DP -= (DW(ii)/wi)*P;
Poles(ii).ChangeCoord() = M*P + Center.XYZ();
P *= MPrim;
DP *= M;
aux.SetLinearForm(1, P, 1, DP, DCenter.XYZ());
DPoles(ii).SetXYZ(aux);
Weights(ii) = wi;
DWeights(ii) = DW(ii);
}
}
void GeomFill_QuasiAngularConvertor::Section(const gp_Pnt& FirstPnt,
const gp_Vec& DFirstPnt,
const gp_Vec& D2FirstPnt,
const gp_Pnt& Center,
const gp_Vec& DCenter,
const gp_Vec& D2Center,
const gp_Vec& Dir,
const gp_Vec& DDir,
const gp_Vec& D2Dir,
const Standard_Real Angle,
const Standard_Real DAngle,
const Standard_Real D2Angle,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfVec& DPoles,
TColgp_Array1OfVec& D2Poles,
TColStd_Array1OfReal& Weights,
TColStd_Array1OfReal& DWeights,
TColStd_Array1OfReal& D2Weights)
{
Standard_Integer Ordre = 7;
math_Vector DVx(1, Ordre), DVy(1, Ordre), DVw(1, Ordre),
D2Vx(1, Ordre), D2Vy(1, Ordre), D2Vw(1, Ordre);
math_Vector DPx(1, Ordre), DPy(1, Ordre), DW(1, Ordre),
D2Px(1, Ordre), D2Py(1, Ordre), D2W(1, Ordre);
Standard_Integer ii;
Standard_Real aux, daux, b, b2, c, c2, bpr, bsc;
gp_Vec V1(Center, FirstPnt), V1Prim, V1Secn, V2;
// Calcul des transformations
gp_XYZ auxyz;
Standard_Real Sina, Cosa;
gp_Mat Rot, RotPrim, RotSecn, D, DPrim, DSecn, DDP, Maux;
// La rotation s'ecrit I + sin(Ang) * D + (1. - cos(Ang)) * D*D
// ou D est l'application x -> Dir ^ x
Rot.SetRotation(Dir.XYZ(), Angle/2);
// La derive s'ecrit donc :
// AngPrim * (sin(Ang)*D*D + cos(Ang)*D)
// + sin(Ang)*DPrim + (1. - cos(Ang)) *(DPrim*D + D*DPrim)
Sina = Sin(Angle/2);
Cosa = Cos(Angle/2);
D.SetCross(Dir.XYZ());
DPrim.SetCross(DDir.XYZ());
DSecn.SetCross(D2Dir.XYZ());
DDP = (DPrim.Multiplied(D)).Added(D.Multiplied(DPrim));
RotPrim = (D.Powered(2)).Multiplied(Sina);
RotPrim += D.Multiplied(Cosa);
RotPrim *= DAngle/2;
RotPrim += DPrim.Multiplied(Sina);
RotPrim += DDP.Multiplied(1-Cosa);
RotSecn = (D.Powered(2)).Multiplied(Sina);
RotSecn += D.Multiplied(Cosa);
RotSecn *= D2Angle/2;
Maux = (D.Powered(2)).Multiplied(Cosa);
Maux -= D.Multiplied(Sina);
Maux *= DAngle/2;
Maux += DDP.Multiplied(2*Sina);
Maux += DPrim.Multiplied(2*Cosa);
Maux *= DAngle/2;
RotSecn += Maux;
Maux = (DSecn.Multiplied(D)).Added(D.Multiplied(DSecn));
Maux += (DPrim.Powered(2)).Multiplied(2);
Maux *= 1 - Cosa;
Maux += DSecn.Multiplied(Sina);
RotSecn += Maux;
V1Prim = DFirstPnt - DCenter;
auxyz = (D2FirstPnt - D2Center).XYZ().Multiplied(Rot);
auxyz += 2*(V1Prim.XYZ().Multiplied(RotPrim));
auxyz += V1.XYZ().Multiplied(RotSecn);
V1Secn.SetXYZ(auxyz);
auxyz = V1Prim.XYZ().Multiplied(Rot);
auxyz += V1.XYZ().Multiplied(RotPrim);
V1Prim.SetXYZ(auxyz);
auxyz = V1.XYZ();
auxyz.Multiply(Rot);
V1.SetXYZ(auxyz);
V2 = Dir^V1;
gp_Mat M (V1.X(), V2.X(), 0,
V1.Y(), V2.Y(), 0,
V1.Z(), V2.Z(), 0);
V2 = (DDir.Crossed(V1)).Added(Dir.Crossed(V1Prim));
gp_Mat MPrim (V1Prim.X(), V2.X(), 0,
V1Prim.Y(), V2.Y(), 0,
V1Prim.Z(), V2.Z(), 0);
V2 = DDir^V1Prim;
V2 *= 2;
V2 += (D2Dir.Crossed(V1)).Added(Dir.Crossed(V1Secn));
gp_Mat MSecn (V1Secn.X(), V2.X(), 0,
V1Secn.Y(), V2.Y(), 0,
V1Secn.Z(), V2.Z(), 0);
// Calcul des coeff -----------
Standard_Real tan_b, dtan_b, d2tan_b;
Standard_Real beta, beta2, beta3, beta4, beta5, beta6, betaprim, betasecn;
Standard_Real betaprim2, bpr2;
beta = Angle/4;
betaprim = DAngle/4;
betasecn = D2Angle/4;
beta2 = beta * beta;
beta3 = beta * beta2;
beta4 = beta2*beta2;
beta5 = beta3*beta2;
beta6 = beta3*beta3;
betaprim2 = betaprim * betaprim;
if (Abs(beta) < NullAngle) {
// On calcul b par D.L
Standard_Real cf =-2.0/21;
Standard_Real Num, Denom, aux;
Num = 0.2 + cf*beta2;
Denom = 1+0.2*beta2;
aux = (cf*Denom - 0.2*Num)/(Denom*Denom);
b = - Num/Denom;
bpr = -2*beta*betaprim*aux;
bsc = 2*aux*(betaprim2 + beta*betasecn - 2*beta*betaprim2);
}
else {
b = ((Standard_Real) -1)/beta2;
bpr = (2*betaprim) / beta3;
bsc = (2*betasecn - 6*betaprim*(betaprim/beta)) / beta3;
if ((PI/2 - beta)> NullAngle) {
tan_b = Tan(beta);
dtan_b = betaprim * (1 + tan_b*tan_b);
d2tan_b = betasecn * (1 + tan_b*tan_b)
+ 2*betaprim * tan_b * dtan_b;
b2 = tan_b - beta;
b += beta / (3*b2);
aux = betaprim*tan_b - beta*dtan_b;
bpr += aux / (3*b2*b2);
daux = betasecn*tan_b - beta*d2tan_b;
bsc += (daux - 2*aux*betaprim*tan_b*tan_b/b2)/(3*b2*b2);
}
}
c = ((Standard_Real) 1)/ 3 + b;
b2 = b*b;
c2 = c*c;
bpr2 = bpr * bpr;
// X = U*U - V*V
Vx(3) = beta2*(2*b - 1);
Vx(5) = beta4*(b2 - 2*c);
Vx(7) = -beta6*c2;
DVx.Init(0);
DVx(3) = 2*(beta*betaprim*(2*b - 1) + bpr*beta2);
DVx(5) = 4*beta3*betaprim*(b2 - 2*c) + 2*beta4*bpr*(b-1);
DVx(7) = - 6*beta5*betaprim*c2 - 2*beta6*bpr*c;
D2Vx.Init(0);
D2Vx(3) = 2*((betaprim2+beta*betasecn)*(2*b - 1)
+ 8*beta*betaprim*bpr
+ bsc*beta2);
D2Vx(5) = 4*(b2 - 2*c)*(3*beta2*betaprim2 + beta3*betasecn)
+ 16*beta3*betaprim*bpr*(b-1)
+ 2*beta4*(bsc*(b-1)+bpr2);
D2Vx(7) = - 6 * c2 * (5*beta4*betaprim2+beta5*betasecn)
- 24*beta5*betaprim*bpr*c
- 2*beta6*(bsc*c + bpr2);
//Y = 2*U*V
Vy(2) = 2*beta;
Vy(4) = beta3*2*(c+b);
Vy(6) = 2*beta5*b*c;
DVy.Init(0);
DVy(2) = 2*betaprim;
DVy(4) = 6*beta2*betaprim*(b+c) + 4*beta3*bpr;
DVy(6) = 10*beta4*betaprim*b*c + 2*beta5*bpr*(b+c);
D2Vy.Init(0);
D2Vy(2) = 2*betasecn;
D2Vy(4) = 6*(b+c)*(2*beta*betaprim2 + beta2*betasecn)
+ 24*beta2*betaprim*bpr*(b+c)
+ 4*beta3*bsc;
D2Vy(6) = 10*b*c*(4*beta3*betaprim2 + beta4*betasecn)
+ 40 * beta4*betaprim*bpr*(b+c)
+ 2*beta5*(bsc*(b+c)+ 2*bpr2);
// W = U*U + V*V
Vw(3) = beta2*(1 + 2*b);
Vw(5) = beta4*(2*c + b2);
Vw(7) = beta6*c2;
DVw.Init(0);
DVw(3) = 2*(beta*betaprim*(1 + 2*b) + beta2*bpr);
DVw(5) = 4*beta3*betaprim*(2*c + b2) + 2*beta4*bpr*(b+1);
DVw(7) = 6*beta5*betaprim*c2 + 2*beta6*bpr*c;
D2Vw.Init(0);
D2Vw(3) = 2*((betaprim2+beta*betasecn)*(2*b + 1)
+ 8*beta*betaprim*bpr
+ bsc*beta2);
D2Vw(5) = 4*(b2 + 2*c)*(3*beta2*betaprim2 + beta3*betasecn)
+ 16*beta3*betaprim*bpr*(b+11)
+ 2*beta4*(bsc*(b+1)+bpr2);
D2Vw(7) = 6 * c2 * (5*beta4*betaprim2+beta5*betasecn)
+ 24*beta5*betaprim*bpr*c
+ 2*beta6*(bsc*c + bpr2);
// Calcul des poles
Px = B * Vx;
Py = B * Vy;
W.Multiply(B, Vw);
DPx = B * DVx;
DPy = B * DVy;
DW.Multiply(B, DVw);
D2Px = B * D2Vx;
D2Py = B * D2Vy;
D2W.Multiply(B, D2Vw);
gp_XYZ P, DP, D2P;
Standard_Real wi, dwi;
for (ii=1; ii<=Ordre; ii++) {
wi = W(ii);
dwi = DW(ii);
P.SetCoord(Px(ii)/wi, Py(ii)/wi, 0);
DP.SetCoord(DPx(ii)/wi, DPy(ii)/wi, 0);
D2P.SetCoord(D2Px(ii)/wi, D2Py(ii)/wi, 0);
D2P -= 2*(dwi/wi)*DP;
D2P += (2*Pow(dwi/wi, 2) - D2W(ii)/wi)*P;
DP -= (DW(ii)/wi)*P;
Poles(ii).ChangeCoord() = M*P + Center.XYZ();
auxyz.SetLinearForm(1, MPrim*P,
1, M*DP,
DCenter.XYZ());
DPoles(ii).SetXYZ(auxyz);
P *= MSecn;
DP *= MPrim;
D2P*= M;
auxyz.SetLinearForm(1, P,
2, DP,
1, D2P,
D2Center.XYZ());
D2Poles(ii).SetXYZ(auxyz);
Weights(ii) = wi;
DWeights(ii) = dwi;
D2Weights(ii) = D2W(ii);
}
}

View File

@@ -0,0 +1,74 @@
-- File: GeomFill_SectionGenerator.cdl
-- Created: Fri Feb 18 15:37:04 1994
-- Author: Bruno DUMORTIER
-- <dub@fuegox>
---Copyright: Matra Datavision 1994
class SectionGenerator from GeomFill inherits Profiler from GeomFill
---Purpose: gives the functions needed for instantiation from
-- AppSurf in AppBlend. Allow to evaluate a surface
-- passing by all the curves if the Profiler.
uses
Array1OfPnt from TColgp,
Array1OfVec from TColgp,
Array1OfPnt2d from TColgp,
Array1OfVec2d from TColgp,
Array1OfReal from TColStd,
HArray1OfReal from TColStd,
Array1OfInteger from TColStd
is
Create returns SectionGenerator from GeomFill;
SetParam(me : in out ; Params : HArray1OfReal from TColStd);
GetShape(me; NbPoles : out Integer from Standard;
NbKnots : out Integer from Standard;
Degree : out Integer from Standard;
NbPoles2d : out Integer from Standard)
is static;
Knots(me; TKnots: out Array1OfReal from TColStd)
is static;
Mults(me; TMults: out Array1OfInteger from TColStd)
is static;
Section(me; P : Integer from Standard;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
Poles2d : out Array1OfPnt2d from TColgp;
DPoles2d : out Array1OfVec2d from TColgp;
Weigths : out Array1OfReal from TColStd;
DWeigths : out Array1OfReal from TColStd)
---Purpose: Used for the first and last section
-- The method returns Standard_True if the derivatives
-- are computed, otherwise it returns Standard_False.
returns Boolean from Standard
is static;
Section(me; P : Integer from Standard;
Poles : out Array1OfPnt from TColgp;
Poles2d : out Array1OfPnt2d from TColgp;
Weigths : out Array1OfReal from TColStd)
is static;
Parameter(me; P: Integer)
---Purpose: Returns the parameter of Section<P>, to impose it for the
-- approximation.
returns Real from Standard
is static;
fields
myParams : HArray1OfReal from TColStd is protected;
end SectionGenerator;

View File

@@ -0,0 +1,134 @@
// File: GeomFill_SectionGenerator.cxx
// Created: Fri Feb 18 15:59:35 1994
// Author: Bruno DUMORTIER
// <dub@fuegox>
#include <GeomFill_SectionGenerator.ixx>
#include <Geom_BSplineCurve.hxx>
//=======================================================================
//function : GeomFill_SectionGenerator
//purpose :
//=======================================================================
GeomFill_SectionGenerator::GeomFill_SectionGenerator()
{
if ( mySequence.Length() > 1 ) {
Handle(TColStd_HArray1OfReal) HPar
= new (TColStd_HArray1OfReal) (1,mySequence.Length());
for (Standard_Integer i = 1; i<=mySequence.Length(); i++) {
HPar->ChangeValue(i) = i-1;
}
SetParam(HPar);
}
}
//=======================================================================
//function : GeomFill_SectionGenerator
//purpose :
//=======================================================================
void GeomFill_SectionGenerator::SetParam(const Handle_TColStd_HArray1OfReal & Params)
{
Standard_Integer ii, L = Params->Upper()-Params->Lower()+1;
myParams = Params;
for (ii=1; ii<=L; ii++) {
myParams->SetValue(ii,Params->Value(Params->Lower()+ii-1));
}
}
//=======================================================================
//function : GetShape
//purpose :
//=======================================================================
void GeomFill_SectionGenerator::GetShape(Standard_Integer& NbPoles,
Standard_Integer& NbKnots,
Standard_Integer& Degree,
Standard_Integer& NbPoles2d) const
{
Handle(Geom_BSplineCurve) C =
Handle(Geom_BSplineCurve)::DownCast(mySequence(1));
NbPoles = C->NbPoles();
NbKnots = C->NbKnots();
Degree = C->Degree();
NbPoles2d = 0;
}
//=======================================================================
//function : Knots
//purpose :
//=======================================================================
void GeomFill_SectionGenerator::Knots(TColStd_Array1OfReal& TKnots) const
{
(Handle(Geom_BSplineCurve)::DownCast(mySequence(1)))->Knots(TKnots);
}
//=======================================================================
//function : Mults
//purpose :
//=======================================================================
void GeomFill_SectionGenerator::Mults(TColStd_Array1OfInteger& TMults) const
{
(Handle(Geom_BSplineCurve)::DownCast(mySequence(1)))->Multiplicities(TMults);
}
//=======================================================================
//function : Section
//purpose :
//=======================================================================
Standard_Boolean GeomFill_SectionGenerator::Section
(const Standard_Integer P,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfVec& , //DPoles,
TColgp_Array1OfPnt2d& Poles2d,
TColgp_Array1OfVec2d& , //DPoles2d,
TColStd_Array1OfReal& Weigths,
TColStd_Array1OfReal& //DWeigths
) const
{
Section(P , Poles, Poles2d, Weigths);
return Standard_False;
}
//=======================================================================
//function : Section
//purpose :
//=======================================================================
void GeomFill_SectionGenerator::Section
(const Standard_Integer P,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfPnt2d& , //Poles2d,
TColStd_Array1OfReal& Weigths ) const
{
Handle(Geom_BSplineCurve) C =
Handle(Geom_BSplineCurve)::DownCast(mySequence(P));
C->Poles(Poles);
C->Weights(Weigths);
}
//=======================================================================
//function : Parameter
//purpose :
//=======================================================================
Standard_Real GeomFill_SectionGenerator::Parameter
(const Standard_Integer P) const
{
return myParams->Value(P);
}

View File

@@ -0,0 +1,218 @@
-- File: GeomFill_SectionLaw.cdl
-- Created: Thu Nov 20 17:08:30 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
deferred class SectionLaw from GeomFill inherits TShared from MMgt
---Purpose: To define section law in sweeping
uses
BSplineSurface from Geom,
Curve from Geom,
HCurve from Adaptor3d,
Shape from GeomAbs,
Pnt from gp,
Array1OfPnt from TColgp,
Array1OfVec from TColgp,
Array1OfInteger from TColStd,
Array1OfReal from TColStd
raises NotImplemented ,
DomainError,
OutOfRange from Standard
is
--
--========== To compute Sections and derivatives Sections
--
D0(me : mutable;
Param: Real;
Poles : out Array1OfPnt from TColgp;
Weigths : out Array1OfReal from TColStd)
---Purpose: compute the section for v = param
returns Boolean is deferred;
D1(me : mutable;
Param: Real;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
Weigths : out Array1OfReal from TColStd;
DWeigths : out Array1OfReal from TColStd)
---Purpose: compute the first derivative in v direction of the
-- section for v = param
-- Warning : It used only for C1 or C2 aproximation
returns Boolean
raises NotImplemented
is virtual;
D2(me : mutable;
Param: Real;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
D2Poles : out Array1OfVec from TColgp;
Weigths : out Array1OfReal from TColStd;
DWeigths : out Array1OfReal from TColStd;
D2Weigths : out Array1OfReal from TColStd)
---Purpose: compute the second derivative in v direction of the
-- section for v = param
-- Warning : It used only for C2 aproximation
returns Boolean
raises NotImplemented
is virtual;
BSplineSurface(me)
---Purpose: give if possible an bspline Surface, like iso-v are the
-- section. If it is not possible this methode have to
-- get an Null Surface. It is the default implementation.
returns BSplineSurface from Geom
is virtual;
SectionShape(me; NbPoles : out Integer from Standard;
NbKnots : out Integer from Standard;
Degree : out Integer from Standard)
---Purpose: get the format of an section
is deferred;
Knots(me; TKnots: out Array1OfReal from TColStd)
---Purpose: get the Knots of the section
is deferred;
Mults(me; TMults: out Array1OfInteger from TColStd)
---Purpose: get the Multplicities of the section
is deferred;
IsRational(me)
---Purpose: Returns if the sections are rationnal or not
returns Boolean is deferred;
IsUPeriodic(me)
---Purpose: Returns if the sections are periodic or not
returns Boolean is deferred;
IsVPeriodic(me)
---Purpose: Returns if law is periodic or not
returns Boolean is deferred;
--
-- =================== Management of continuity ===================
--
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>.
-- May be one if Continuity(me) >= <S>
returns Integer is deferred;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is deferred;
SetInterval(me: mutable; First, Last: Real from Standard)
---Purpose: Sets the bounds of the parametric interval on
-- the function
-- This determines the derivatives in these values if the
-- function is not Cn.
is deferred;
GetInterval(me; First, Last: out Real from Standard)
---Purpose: Gets the bounds of the parametric interval on
-- the function
is deferred;
GetDomain(me; First, Last: out Real from Standard)
---Purpose: Gets the bounds of the function parametric domain.
-- Warning: This domain it is not modified by the
-- SetValue method
is deferred;
-- ===================== To help computation of Tolerance ======
-- Evaluation of error, in 2d space, or on rational function, is
-- difficult. The following methods can help the approximation to
-- make good evaluation and use good tolerances.
--
-- It is not necessary for the following informations to be very
-- precise. A fast evaluation is sufficient.
GetTolerance(me;
BoundTol, SurfTol, AngleTol : Real;
Tol3d : out Array1OfReal)
---Purpose: Returns the tolerances associated at each poles to
-- reach in approximation, to satisfy: BoundTol error
-- at the Boundary AngleTol tangent error at the
-- Boundary (in radian) SurfTol error inside the
-- surface.
is deferred;
SetTolerance(me : mutable; Tol3d, Tol2d : Real)
---Purpose: Is usefull, if (me) have to run numerical
-- algorithm to perform D0, D1 or D2
-- The default implementation make nothing.
is virtual;
BarycentreOfSurf(me)
---Purpose: Get the barycentre of Surface.
-- An very poor estimation is sufficent.
-- This information is usefull to perform well
-- conditioned rational approximation.
-- Warning: Used only if <me> IsRational
returns Pnt from gp
raises NotImplemented
is virtual;
MaximalSection(me) returns Real
---Purpose: Returns the length of the greater section. This
-- information is usefull to G1's control.
-- Warning: With an little value, approximation can be slower.
is deferred;
GetMinimalWeight(me; Weigths : out Array1OfReal from TColStd)
---Purpose: Compute the minimal value of weight for each poles
-- in all sections.
-- This information is usefull to control error
-- in rational approximation.
-- Warning: Used only if <me> IsRational
raises NotImplemented
is virtual;
--- Particular case
IsConstant(me; Error : out Real)
---Purpose: Say if all sections are equals
returns Boolean
is virtual;
ConstantSection(me)
---Purpose: Return a copy of the constant Section, if me
-- IsConstant
--
returns Curve from Geom
raises DomainError -- If <me> is not Constante
is virtual;
IsConicalLaw(me; Error : out Real)
---Purpose: Returns True if all section are circle, with same
-- plane,same center and linear radius evolution
-- Return False by Default.
returns Boolean
is virtual;
CirclSection(me; Param : Real)
---Purpose: Return the circle section at parameter <Param>, if
-- <me> a IsConicalLaw
returns Curve from Geom
raises DomainError -- If <me> is not a Conical Law
is virtual;
end SectionLaw;

View File

@@ -0,0 +1,70 @@
// File: GeomFill_SectionLaw.cxx
// Created: Fri Nov 21 15:19:07 1997
// Author: Philippe MANGIN
// <pmn@sgi29>
#include <GeomFill_SectionLaw.ixx>
Standard_Boolean GeomFill_SectionLaw::D1(const Standard_Real,TColgp_Array1OfPnt&,TColgp_Array1OfVec&,TColStd_Array1OfReal&,TColStd_Array1OfReal& )
{
Standard_NotImplemented::Raise("GeomFill_SectionLaw::D1");
return 0;
}
Standard_Boolean GeomFill_SectionLaw::D2(const Standard_Real,TColgp_Array1OfPnt& ,TColgp_Array1OfVec&,TColgp_Array1OfVec&,TColStd_Array1OfReal&,TColStd_Array1OfReal&,TColStd_Array1OfReal&)
{
Standard_NotImplemented::Raise("GeomFill_SectionLaw::D2");
return 0;
}
Handle(Geom_BSplineSurface) GeomFill_SectionLaw::BSplineSurface() const
{
Handle(Geom_BSplineSurface) BS;
BS.Nullify();
return BS;
}
void GeomFill_SectionLaw::SetTolerance(const Standard_Real ,const Standard_Real)
{
//Ne fait Rien
}
gp_Pnt GeomFill_SectionLaw::BarycentreOfSurf() const
{
Standard_NotImplemented::Raise("GeomFill_SectionLaw::BarycentreOfSurf");
return gp_Pnt(0.0, 0.0, 0.0);
}
void GeomFill_SectionLaw::GetMinimalWeight(TColStd_Array1OfReal&) const
{
Standard_NotImplemented::Raise("GeomFill_SectionLaw::GetMinimalWeight");
}
Standard_Boolean GeomFill_SectionLaw::IsConstant(Standard_Real& Error) const
{
Error = 0.;
return Standard_False;
}
Handle(Geom_Curve) GeomFill_SectionLaw::ConstantSection() const
{
Handle(Geom_Curve) C;
Standard_DomainError::Raise("GeomFill_SectionLaw::ConstantSection");
return C;
}
Standard_Boolean GeomFill_SectionLaw::IsConicalLaw(Standard_Real& Error) const
{
Error = 0.;
return Standard_False;
}
Handle(Geom_Curve) GeomFill_SectionLaw::
CirclSection(const Standard_Real) const
{
Handle(Geom_Curve) C;
Standard_DomainError::Raise("GeomFill_SectionLaw::CirclSection");
return C;
}

View File

@@ -0,0 +1,100 @@
-- File: GeomFill_SectionPlacement.cdl
-- Created: Mon Dec 15 16:25:44 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
class SectionPlacement from GeomFill
---Purpose: To place section in sweep Function
---Level: Advanced
uses
LocationLaw from GeomFill,
Geometry from Geom,
Curve from Geom,
HCurve from Adaptor3d,
Curve from GeomAdaptor,
ExtPC from Extrema,
Trsf from gp,
Mat from gp,
Ax1 from gp,
Vec from gp,
Pnt from gp
raises
NotDone
is
Create(L : LocationLaw from GeomFill;
Section : Geometry from Geom)
returns SectionPlacement from GeomFill;
SetLocation(me : in out; L : LocationLaw from GeomFill)
---Purpose: To change the section Law
is static;
Perform(me:in out; Tol : Real)
is static;
Perform(me:in out; Path : HCurve from Adaptor3d;
Tol : Real)
is static;
Perform(me:in out; ParamOnPath : Real;
Tol : Real)
is static;
IsDone(me)
returns Boolean;
ParameterOnPath(me) returns Real;
ParameterOnSection(me) returns Real;
Distance(me) returns Real;
Angle(me) returns Real;
Transformation(me; WithTranslation : Boolean;
WithCorrection : Boolean = Standard_False)
returns Trsf from gp;
Section(me; WithTranslation : Boolean)
---Purpose: Compute the Section, in the coordinate syteme given by
-- the Location Law.
-- If <WithTranslation> contact beetween
-- <Section> and <Path> is forced.
returns Curve from Geom;
ModifiedSection(me; WithTranslation : Boolean)
---Purpose: Compute the Section, in the coordinate syteme given by
-- the Location Law.
-- To have the Normal to section equal to the Location
-- Law Normal. If <WithTranslation> contact beetween
-- <Section> and <Path> is forced.
returns Curve from Geom;
SectionAxis(me; M : Mat from gp;
T, N, BN : out Vec from gp) is private;
Choix(me; Dist, Angle : Real)
returns Boolean
is private;
fields
done : Boolean;
isplan : Boolean;
TheAxe : Ax1 from gp;
Gabarit : Real;
myLaw : LocationLaw from GeomFill;
myAdpSection : Curve from GeomAdaptor;
mySection : Curve from Geom;
SecParam, PathParam, Dist, AngleMax : Real;
myExt : ExtPC from Extrema;
myIsPoint : Boolean from Standard;
myPoint : Pnt from gp;
end ;

View File

@@ -0,0 +1,957 @@
// File: GeomFill_SectionPlacement.cxx
// Created: Mon Dec 15 17:09:47 1997
// Author: Philippe MANGIN
// <pmn@sgi29>
#include <GeomFill_SectionPlacement.ixx>
#include <GeomLib.hxx>
#include <Geom_Plane.hxx>
#include <GeomLProp_CLProps.hxx>
#include <GeomAbs_CurveType.hxx>
#include <GeomAdaptor_HSurface.hxx>
#include <gp_Ax3.hxx>
#include <gp_Ax2.hxx>
#include <gp_Pnt.hxx>
#include <gp_Dir.hxx>
#include <gp_Trsf.hxx>
#include <TColgp_HArray1OfPnt.hxx>
#include <Bnd_Box.hxx>
#include <BndLib_Add3dCurve.hxx>
#include <Precision.hxx>
#include <gp.hxx>
#include <Extrema_ExtCC.hxx>
#include <Extrema_POnCurv.hxx>
#include <IntCurveSurface_HInter.hxx>
#include <IntCurveSurface_IntersectionPoint.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Geom_Line.hxx>
#include <Geom_Conic.hxx>
#include <Geom_BezierCurve.hxx>
#include <Geom_CartesianPoint.hxx>
//===============================================================
// Function :
// Purpose :
//===============================================================
static void Tangente(const Adaptor3d_Curve& Path,
const Standard_Real Param,
gp_Pnt& P,
gp_Vec& Tang)
{
Path.D1(Param, P, Tang);
Standard_Real Norm = Tang.Magnitude();
for (Standard_Integer ii=2; (ii<12) && (Norm < Precision::Confusion());
ii++) {
Tang = Path.DN(Param, ii);
Norm = Tang.Magnitude();
}
if (Norm > 100*gp::Resolution()) Tang /= Norm;
}
static Standard_Real Penalite(const Standard_Real angle,
const Standard_Real dist)
{
Standard_Real penal;
if (dist < 1)
penal = Sqrt(dist);
else if (dist <2)
penal = Pow(dist, 2);
else
penal = dist + 2;
if (angle > 1.e-3) {
penal += 1./angle -2./PI;
}
else {
penal += 1.e3;
}
return penal;
}
static Standard_Real EvalAngle(const gp_Vec& V1,
const gp_Vec& V2)
{
Standard_Real angle;
angle = V1.Angle(V2);
if (angle > PI/2) angle = PI - angle;
return angle;
}
static Standard_Integer NbSamples(const Handle(Geom_Curve)& aCurve)
{
Standard_Real nbs = 100.; //on default
Handle(Geom_Curve) theCurve = aCurve;
if (aCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
theCurve = (Handle(Geom_TrimmedCurve)::DownCast(aCurve))->BasisCurve();
if (theCurve->IsInstance(STANDARD_TYPE(Geom_Line)))
nbs = 1;
else if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
nbs = 4;
else if (theCurve->IsInstance(STANDARD_TYPE(Geom_BezierCurve)))
{
Handle(Geom_BezierCurve) BC = Handle(Geom_BezierCurve)::DownCast(theCurve);
nbs = 3 + BC->NbPoles();
}
else if (theCurve->IsInstance(STANDARD_TYPE(Geom_BSplineCurve)))
{
Handle(Geom_BSplineCurve) BC = Handle(Geom_BSplineCurve)::DownCast(theCurve);
nbs = BC->NbKnots();
nbs *= BC->Degree();
Standard_Real ratio =
(aCurve->LastParameter() - aCurve->FirstParameter())/(BC->LastParameter() - BC->FirstParameter());
nbs *= ratio;
if(nbs < 4.0)
nbs = 4;
}
if (nbs > 300.)
nbs = 300;
return ((Standard_Integer)nbs);
}
//===============================================================
// Function :DistMini
// Purpose : Examine un extrema pour updater <Dist> & <Param>
//===============================================================
static void DistMini(const Extrema_ExtPC& Ext,
const Adaptor3d_Curve& C,
Standard_Real& Dist,
Standard_Real& Param)
{
Standard_Real dist1, dist2;
Standard_Integer ii;
gp_Pnt P1, P2;
Standard_Real Dist2 = RealLast();
Ext.TrimmedSquareDistances(dist1, dist2, P1, P2);
if ( (dist1<Dist2) || (dist2<Dist2) ) {
if (dist1 < dist2) {
Dist2 = dist1;
Param = C.FirstParameter();
}
else {
Dist2 = dist2;
Param = C.LastParameter();
}
}
if (Ext.IsDone())
{
for (ii=1; ii<= Ext.NbExt(); ii++) {
if (Ext.SquareDistance(ii) < Dist2) {
Dist2 = Ext.SquareDistance(ii);
Param = Ext.Point(ii).Parameter();
}
}
}
Dist = sqrt (Dist2);
}
//===============================================================
// Function : Constructeur
// Purpose :
//===============================================================
GeomFill_SectionPlacement::
GeomFill_SectionPlacement(const Handle(GeomFill_LocationLaw)& L,
const Handle(Geom_Geometry)& Section) :
myLaw(L), /* myAdpSection(Section), mySection(Section), */
Dist(RealLast()), AngleMax(0.)
{
done = Standard_False;
isplan = Standard_False;
myIsPoint = Standard_False;
if (Section->IsInstance(STANDARD_TYPE(Geom_CartesianPoint)))
{
myIsPoint = Standard_True;
myPoint = Handle(Geom_CartesianPoint)::DownCast(Section)->Pnt();
isplan = Standard_True;
}
else
{
Handle(Geom_Curve) CurveSection = Handle(Geom_Curve)::DownCast(Section);
myAdpSection.Load(CurveSection);
mySection = CurveSection;
}
Standard_Integer i, j, NbPoles=0;
Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
// Boite d'encombrement de la section pour en deduire le gabarit
Bnd_Box box;
if (myIsPoint)
box.Add(myPoint);
else
BndLib_Add3dCurve::Add(myAdpSection, 1.e-4, box);
box.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
Standard_Real DX = aXmax - aXmin ;
Standard_Real DY = aYmax - aYmin ;
Standard_Real DZ = aZmax - aZmin ;
Gabarit = Sqrt( DX*DX+ DY*DY + DZ*DZ )/2. ;
Gabarit += Precision::Confusion(); // Cas des toute petite
// Initialisation de TheAxe pour les cas singulier
if (!myIsPoint)
{
gp_Pnt P;
gp_Vec V;
Tangente(myAdpSection,
(myAdpSection.FirstParameter()+myAdpSection.LastParameter())/2,
P, V);
TheAxe.SetLocation(P);
TheAxe.SetDirection(V);
// y a t'il un Plan moyen ?
GeomAbs_CurveType TheType = myAdpSection.GetType();
switch (TheType) {
case GeomAbs_Circle:
{
isplan = Standard_True;
TheAxe = myAdpSection.Circle().Axis();
break;
}
case GeomAbs_Ellipse:
{
isplan = Standard_True;
TheAxe = myAdpSection.Ellipse().Axis();
break;
}
case GeomAbs_Hyperbola:
{
isplan = Standard_True;
TheAxe = myAdpSection.Hyperbola().Axis();
break;
}
case GeomAbs_Parabola:
{
isplan = Standard_True;
TheAxe = myAdpSection.Parabola().Axis();
break;
}
case GeomAbs_Line:
{
NbPoles = 0; // Pas de Plan !!
break;
}
case GeomAbs_BezierCurve:
case GeomAbs_BSplineCurve:
{
NbPoles = myAdpSection.NbPoles();
break;
}
default:
NbPoles = 21;
}
if (!isplan && NbPoles>2)
{
// Calcul d'un plan moyen.
Handle(TColgp_HArray1OfPnt) Pnts;
Standard_Real first = myAdpSection.FirstParameter();
Standard_Real last = myAdpSection.LastParameter();
Standard_Real t, delta;
if (myAdpSection.GetType() == GeomAbs_BSplineCurve)
{
Handle(Geom_BSplineCurve) BC =
Handle(Geom_BSplineCurve)::DownCast(myAdpSection.Curve());
Standard_Integer I1, I2, I3, I4;
BC->LocateU( first, Precision::Confusion(), I1, I2 );
BC->LocateU( last, Precision::Confusion(), I3, I4 );
Standard_Integer NbKnots = I3 - I2 + 1;
Standard_Integer NbLocalPnts = 10;
Standard_Integer NbPnts = (NbKnots-1) * NbLocalPnts;
if (I1 != I2)
NbPnts += NbLocalPnts;
if (I3 != I4 && first < BC->Knot(I3))
NbPnts += NbLocalPnts;
if (!myAdpSection.IsClosed())
NbPnts++;
Pnts = new TColgp_HArray1OfPnt(1, NbPnts);
Standard_Integer nb = 1;
if (I1 != I2)
{
Standard_Real locallast = (BC->Knot(I2) < last)? BC->Knot(I2) : last;
delta = (locallast - first) / NbLocalPnts;
for (j = 0; j < NbLocalPnts; j++)
{
t = first + j*delta;
Pnts->SetValue( nb++, myAdpSection.Value(t) );
}
}
for (i = I2; i < I3; i++)
{
t = BC->Knot(i);
delta = (BC->Knot(i+1) - t) / NbLocalPnts;
for (j = 0; j < NbLocalPnts; j++)
{
t += delta;
Pnts->SetValue( nb++, myAdpSection.Value(t) );
}
}
if (I3 != I4 && first < BC->Knot(I3))
{
t = BC->Knot(I3);
delta = (last - t) / NbLocalPnts;
for (j = 0; j < NbLocalPnts; j++)
{
t += delta;
Pnts->SetValue( nb++, myAdpSection.Value(t) );
}
}
if (!myAdpSection.IsClosed())
Pnts->SetValue( nb, myAdpSection.Value(last) );
}
else // other type
{
Standard_Integer NbPnts = NbPoles-1;
if (!myAdpSection.IsClosed())
NbPnts++;
Pnts = new TColgp_HArray1OfPnt(1, NbPnts);
delta = (last - first) / (NbPoles-1);
for (i = 0; i < NbPoles-1; i++)
{
t = first + i*delta;
Pnts->SetValue( i+1, myAdpSection.Value(t) );
}
if (!myAdpSection.IsClosed())
Pnts->SetValue( NbPnts, myAdpSection.Value(last) );
}
Standard_Boolean issing;
gp_Ax2 axe;
GeomLib::AxeOfInertia(Pnts->Array1(), axe, issing, Precision::Confusion());
if (!issing) {
isplan = Standard_True;
TheAxe.SetLocation(axe.Location());
TheAxe.SetDirection(axe.Direction());
}
}
myExt.Initialize(myAdpSection,
myAdpSection.FirstParameter(),
myAdpSection.LastParameter(),
Precision::Confusion());
}
}
//===============================================================
// Function :SetLocation
// Purpose :
//===============================================================
void GeomFill_SectionPlacement::
SetLocation(const Handle(GeomFill_LocationLaw)& L)
{
myLaw = L;
}
//===============================================================
// Function : Perform
// Purpose : Le plus simple
//===============================================================
void GeomFill_SectionPlacement::Perform(const Standard_Real Tol)
{
Handle(Adaptor3d_HCurve) Path;
Path = myLaw->GetCurve();
Perform(Path, Tol);
}
//===============================================================
// Function :Perform
// Purpose : Recherche automatique
//===============================================================
void GeomFill_SectionPlacement::Perform(const Handle(Adaptor3d_HCurve)& Path,
const Standard_Real Tol)
{
Standard_Real IntTol = 1.e-5;
Standard_Real DistCenter = Precision::Infinite();
if (myIsPoint)
{
Extrema_ExtPC Projector(myPoint, Path->Curve(), Precision::Confusion());
DistMini( Projector, Path->Curve(), Dist, PathParam );
AngleMax = PI/2;
}
else
{
PathParam = Path->FirstParameter();
SecParam = myAdpSection.FirstParameter();
Standard_Real distaux, taux, alpha;
gp_Pnt PonPath, PonSec, P;
gp_Vec VRef, dp1;
VRef.SetXYZ(TheAxe.Direction().XYZ());
Tangente( Path->Curve(), PathParam, PonPath, dp1);
PonSec = myAdpSection.Value(SecParam);
Dist = PonPath.Distance(PonSec);
if (Dist > Tol) { // On Cherche un meilleur point sur la section
myExt.Perform(PonPath);
if ( myExt.IsDone() ) {
DistMini(myExt, myAdpSection, Dist, SecParam);
PonSec = myAdpSection.Value(SecParam);
}
}
AngleMax = EvalAngle(VRef, dp1);
if (isplan) AngleMax = PI/2 - AngleMax;
Standard_Boolean Trouve = Standard_False;
Standard_Integer ii;
if (isplan) {
// (1.1) Distances Point-Plan
Standard_Real DistPlan;
gp_Vec V1 (PonPath, TheAxe.Location());
DistPlan = Abs(V1.Dot(VRef));
if (DistPlan <= IntTol)
DistCenter = V1.Magnitude();
gp_Pnt Plast = Path->Value( Path->LastParameter() );
V1.SetXYZ( TheAxe.Location().XYZ() - Plast.XYZ() );
DistPlan = Abs(V1.Dot(VRef));
if (DistPlan <= IntTol)
{
Standard_Real aDist = V1.Magnitude();
if (aDist < DistCenter)
{
DistCenter = aDist;
PonPath = Plast;
PathParam = Path->LastParameter();
}
}
// (1.2) Intersection Plan-courbe
gp_Ax3 axe (TheAxe.Location(), TheAxe.Direction());
Handle(Geom_Plane) plan = new (Geom_Plane)(axe);
Handle(GeomAdaptor_HSurface) adplan =
new (GeomAdaptor_HSurface)(plan);
IntCurveSurface_HInter Intersector;
Intersector.Perform(Path, adplan);
if (Intersector.IsDone())
{
Standard_Real w;
gp_Pnt P;
Standard_Real aDist;
for (ii=1; ii<=Intersector.NbPoints(); ii++)
{
w = Intersector.Point(ii).W();
P = Path->Value( w );
aDist = P.Distance( TheAxe.Location() );
if (aDist < DistCenter)
{
DistCenter = aDist;
PonPath = P;
PathParam = w;
}
}
}
if (!Intersector.IsDone() || Intersector.NbPoints() == 0)
{
Standard_Integer NbPnts = NbSamples( mySection );
TColgp_Array1OfPnt Pnts( 1, NbPnts+1 );
Standard_Real delta = (mySection->LastParameter()-mySection->FirstParameter())/NbPnts;
for (ii = 0; ii <= NbPnts; ii++)
Pnts(ii+1) = mySection->Value( mySection->FirstParameter() + ii*delta );
gp_Pnt BaryCenter;
gp_Dir Xdir, Ydir;
Standard_Real Xgap, Ygap, Zgap;
GeomLib::Inertia( Pnts, BaryCenter, Xdir, Ydir, Xgap, Ygap, Zgap );
gp_Pnt Pfirst = Path->Value( Path->FirstParameter() );
if (Pfirst.Distance(BaryCenter) < Plast.Distance(BaryCenter))
PathParam = Path->FirstParameter();
else
{
PathParam = Path->LastParameter();
Tangente( Path->Curve(), PathParam, PonPath, dp1);
PonSec = myAdpSection.Value(SecParam);
Dist = PonPath.Distance(PonSec);
if (Dist > Tol) { // On Cherche un meilleur point sur la section
myExt.Perform(PonPath);
if ( myExt.IsDone() ) {
DistMini(myExt, myAdpSection, Dist, SecParam);
PonSec = myAdpSection.Value(SecParam);
}
}
AngleMax = EvalAngle(VRef, dp1);
AngleMax = PI/2 - AngleMax;
}
}
/*
// (1.1) Distances Point-Plan
Standard_Real DistPlan;
gp_Vec V1 (PonPath, TheAxe.Location());
DistPlan = Abs(V1.Dot(VRef));
// On examine l'autre extremite
gp_Pnt P;
Tangente(Path->Curve(), Path->LastParameter(), P, dp1);
V1.SetXYZ(TheAxe.Location().XYZ()-P.XYZ());
if (Abs(V1.Dot(VRef)) <= DistPlan ) { // On prend l'autre extremite
alpha = PI/2 - EvalAngle(VRef, dp1);
distaux = PonPath.Distance(PonSec);
if (distaux > Tol) {
myExt.Perform(P);
if ( myExt.IsDone() )
DistMini(myExt, myAdpSection, distaux, taux);
}
else
taux = SecParam;
if (Choix(distaux, alpha)) {
Dist = distaux;
AngleMax = alpha;
PonPath = P;
PathParam = Path->LastParameter();
}
}
// (1.2) Intersection Plan-courbe
gp_Ax3 axe (TheAxe.Location(), TheAxe.Direction());
Handle(Geom_Plane) plan = new (Geom_Plane)(axe);
Handle(GeomAdaptor_HSurface) adplan =
new (GeomAdaptor_HSurface)(plan);
IntCurveSurface_HInter Intersector;
Intersector.Perform(Path, adplan);
if (Intersector.IsDone()) {
Standard_Real w;
gp_Vec V;
for (ii=1; ii<=Intersector.NbPoints(); ii++) {
w = Intersector.Point(ii).W();
//(1.3) test d'angle
Tangente( Path->Curve(), w, P, V);
alpha = PI/2 - EvalAngle(V, VRef);
//(1.4) Test de distance Point-Courbe
myExt.Perform(P);
if ( myExt.IsDone() ) {
DistMini(myExt, myAdpSection, distaux, taux);
if (Choix(distaux, alpha)) {
Dist = distaux;
SecParam = taux;
AngleMax = alpha;
PonPath = P;
PathParam = w;
PonSec = myAdpSection.Value(SecParam);
}
}
else {
distaux = P.Distance(PonSec);
if (Choix(distaux, alpha)) {
Dist = distaux;
AngleMax = alpha;
PonPath = P;
PathParam = w;
}
}
}
}
*/
#if DEB
if (Intersector.NbPoints() == 0) {
Intersector.Dump();
}
#endif
}
// Cas General
if (! isplan) {
// (2.1) Distance avec les extremites ...
myExt.Perform(PonPath);
if ( myExt.IsDone() ) {
DistMini(myExt, myAdpSection, distaux, taux);
if (distaux < Dist) {
Dist = distaux;
SecParam = taux;
}
}
Trouve = (Dist <= Tol);
if (!Trouve) {
Tangente( Path->Curve(), Path->LastParameter(), P, dp1);
alpha = EvalAngle(VRef, dp1);
myExt.Perform(P);
if ( myExt.IsDone() ) {
if ( myExt.IsDone() ) {
DistMini(myExt, myAdpSection, distaux, taux);
if (Choix(distaux, alpha)) {
Dist = distaux;
SecParam = taux;
AngleMax = alpha;
PonPath = P;
PathParam = Path->LastParameter();
}
}
}
Trouve = (Dist <= Tol);
}
// (2.2) Distance courbe-courbe
if (!Trouve) {
Extrema_ExtCC Ext(Path->Curve(), myAdpSection,
Path->FirstParameter(), Path->LastParameter(),
myAdpSection.FirstParameter(),
myAdpSection.LastParameter(),
Path->Resolution(Tol/100),
myAdpSection.Resolution(Tol/100));
if (Ext.IsDone()) {
Extrema_POnCurv P1, P2;
for (ii=1; ii<=Ext.NbExt(); ii++) {
distaux = sqrt (Ext.SquareDistance(ii));
Ext.Points(ii, P1, P2);
Tangente(Path->Curve(), P1.Parameter(), P, dp1);
alpha = EvalAngle(VRef, dp1);
if (Choix(distaux, alpha)) {
Trouve = Standard_True;
Dist = distaux;
PathParam = P1.Parameter();
SecParam = P2.Parameter();
PonSec = P2.Value();
PonPath = P;
AngleMax = alpha;
}
}
}
if (!Trouve){
// Si l'on a toujours rien, on essai une distance point/path
// c'est la derniere chance.
Extrema_ExtPC PExt;
PExt.Initialize(Path->Curve(),
Path->FirstParameter(),
Path->LastParameter(),
Precision::Confusion());
PExt.Perform(PonSec);
if ( PExt.IsDone() ) {
// modified for OCC13595 Tue Oct 17 15:00:08 2006.BEGIN
// DistMini(PExt, myAdpSection, distaux, taux);
DistMini(PExt, Path->Curve(), distaux, taux);
// modified for OCC13595 Tue Oct 17 15:00:11 2006.END
Tangente(Path->Curve(), taux, P, dp1);
alpha = EvalAngle(VRef, dp1);
if (Choix(distaux, alpha)) {
Dist = distaux;
PonPath = P;
AngleMax = alpha;
PathParam = taux;
}
}
}
}
}
}
done = Standard_True;
}
//===============================================================
// Function : Perform
// Purpose : Calcul le placement pour un parametre donne.
//===============================================================
void GeomFill_SectionPlacement::Perform(const Standard_Real Param,
const Standard_Real Tol)
{
done = Standard_True;
Handle(Adaptor3d_HCurve) Path;
Path = myLaw->GetCurve();
PathParam = Param;
if (myIsPoint)
{
gp_Pnt PonPath = Path->Value( PathParam );
Dist = PonPath.Distance(myPoint);
AngleMax = PI/2;
}
else
{
SecParam = myAdpSection.FirstParameter();
// Standard_Real distaux, taux, alpha;
// gp_Pnt PonPath, PonSec, P;
gp_Pnt PonPath, PonSec;
gp_Vec VRef, dp1;
VRef.SetXYZ(TheAxe.Direction().XYZ());
Tangente( Path->Curve(), PathParam, PonPath, dp1);
PonSec = myAdpSection.Value(SecParam);
Dist = PonPath.Distance(PonSec);
if (Dist > Tol) { // On Cherche un meilleur point sur la section
myExt.Perform(PonPath);
if ( myExt.IsDone() ) {
DistMini(myExt, myAdpSection, Dist, SecParam);
PonSec = myAdpSection.Value(SecParam);
}
}
AngleMax = EvalAngle(VRef, dp1);
if (isplan) AngleMax = PI/2 - AngleMax;
}
done = Standard_True;
}
//===============================================================
// Function :IsDone
// Purpose :
//===============================================================
Standard_Boolean GeomFill_SectionPlacement::IsDone() const
{
return done;
}
//===============================================================
// Function : ParameterOnPath
// Purpose :
//===============================================================
Standard_Real GeomFill_SectionPlacement::ParameterOnPath() const
{
return PathParam;
}
//===============================================================
// Function : ParameterOnSection
// Purpose :
//===============================================================
Standard_Real GeomFill_SectionPlacement::ParameterOnSection() const
{
return SecParam;
}
//===============================================================
// Function : Distance
// Purpose :
//===============================================================
Standard_Real GeomFill_SectionPlacement::Distance() const
{
return Dist;
}
//===============================================================
// Function : Angle
// Purpose :
//===============================================================
Standard_Real GeomFill_SectionPlacement::Angle() const
{
return AngleMax;
}
//===============================================================
// Function : Transformation
// Purpose :
//===============================================================
gp_Trsf GeomFill_SectionPlacement::Transformation(
const Standard_Boolean WithTranslation,
const Standard_Boolean WithCorrection) const
{
gp_Vec V;
gp_Mat M;
gp_Dir DT, DN, D;
// modified by NIZHNY-MKK Fri Oct 17 15:27:07 2003
gp_Pnt P(0., 0., 0.), PSection(0., 0., 0.);
// Calcul des reperes
myLaw->D0(PathParam, M, V);
P.SetXYZ(V.XYZ());
D.SetXYZ (M.Column(3));
DN.SetXYZ(M.Column(1));
gp_Ax3 Paxe(P, D, DN);
if (WithTranslation || WithCorrection) {
if (myIsPoint)
PSection = myPoint;
else
PSection = mySection->Value(SecParam);
}
// modified by NIZHNY-MKK Wed Oct 8 15:03:19 2003.BEGIN
gp_Trsf Rot;
if (WithCorrection && !myIsPoint) {
Standard_Real angle;
if (!isplan)
Standard_Failure::Raise("Illegal usage: can't rotate non-planar profile");
gp_Dir ProfileNormal = TheAxe.Direction();
gp_Dir SpineStartDir = Paxe.Direction();
if (! ProfileNormal.IsParallel( SpineStartDir, Precision::Angular() )) {
gp_Dir DirAxeOfRotation = ProfileNormal ^ SpineStartDir;
angle = ProfileNormal.AngleWithRef( SpineStartDir, DirAxeOfRotation );
gp_Ax1 AxeOfRotation( TheAxe.Location(), DirAxeOfRotation );
Rot.SetRotation( AxeOfRotation, angle );
}
PSection.Transform(Rot);
}
// modified by NIZHNY-MKK Wed Oct 8 15:03:21 2003.END
if (WithTranslation) {
P.ChangeCoord().SetLinearForm(-1,PSection.XYZ(),
V.XYZ());
}
else {
P.SetCoord(0., 0., 0.);
}
gp_Ax3 Saxe(P, gp::DZ(), gp::DX());
// Transfo
gp_Trsf Tf;
Tf.SetTransformation(Saxe, Paxe);
if (WithCorrection) {
// modified by NIZHNY-MKK Fri Oct 17 15:26:36 2003.BEGIN
// Standard_Real angle;
// gp_Trsf Rot;
// if (!isplan)
// Standard_Failure::Raise("Illegal usage: can't rotate non-planar profile");
// gp_Dir ProfileNormal = TheAxe.Direction();
// gp_Dir SpineStartDir = Paxe.Direction();
// if (! ProfileNormal.IsParallel( SpineStartDir, Precision::Angular() ))
// {
// gp_Dir DirAxeOfRotation = ProfileNormal ^ SpineStartDir;
// angle = ProfileNormal.AngleWithRef( SpineStartDir, DirAxeOfRotation );
// gp_Ax1 AxeOfRotation( TheAxe.Location(), DirAxeOfRotation );
// Rot.SetRotation( AxeOfRotation, angle );
// }
// modified by NIZHNY-MKK Fri Oct 17 15:26:42 2003.END
Tf *= Rot;
}
return Tf;
}
//===============================================================
// Function : Section
// Purpose :
//===============================================================
Handle(Geom_Curve) GeomFill_SectionPlacement::
Section(const Standard_Boolean WithTranslation) const
{
Handle(Geom_Curve) TheSection =
Handle(Geom_Curve)::DownCast(mySection->Copy());
TheSection->Transform(Transformation(WithTranslation, Standard_False));
return TheSection;
}
//===============================================================
// Function :
// Purpose :
//===============================================================
Handle(Geom_Curve) GeomFill_SectionPlacement::
ModifiedSection(const Standard_Boolean WithTranslation) const
{
Handle(Geom_Curve) TheSection =
Handle(Geom_Curve)::DownCast(mySection->Copy());
TheSection->Transform(Transformation(WithTranslation, Standard_True));
return TheSection;
}
//===============================================================
// Function :SectionAxis
// Purpose :
//===============================================================
void GeomFill_SectionPlacement::SectionAxis(const gp_Mat& M,
gp_Vec& T,
gp_Vec& N,
gp_Vec& BN) const
{
Standard_Real Eps = 1.e-10;
gp_Dir D;
gp_Vec PathNormal;
GeomLProp_CLProps CP(mySection, SecParam, 2, Eps);
if (CP.IsTangentDefined()) {
CP.Tangent(D);
T.SetXYZ(D.XYZ());
T.Normalize();
if (CP.Curvature() > Eps) {
CP.Normal(D);
N.SetXYZ(D.XYZ());
}
else {
// Cas ambigu, on essai de recuperer la normal a la trajectoire
// Reste le probleme des points d'inflexions, qui n'est pas
// bien traiter par LProp (pas de recuperation de la normal) :
// A voir...
PathNormal.SetXYZ(M.Column(1));
PathNormal.Normalize();
BN = T ^ PathNormal;
if (BN.Magnitude() > Eps) {
BN.Normalize();
//N = BN ^ T;
}
N = BN ^ T;
}
}
else { // Cas indefinie, on prend le triedre
// complet sur la trajectoire
T.SetXYZ(M.Column(3));
N.SetXYZ(M.Column(2));
}
BN = T ^ N;
}
//===============================================================
// Function :Choix
// Purpose : Decide si le couple (dist, angle) est "meilleur" que
// couple courrant.
//===============================================================
Standard_Boolean GeomFill_SectionPlacement::Choix(const Standard_Real dist,
const Standard_Real angle) const
{
Standard_Real evoldist, evolangle;
evoldist = dist - Dist;
evolangle = angle - AngleMax;
// (1) Si la gain en distance est > que le gabarit, on prend
if (evoldist < - Gabarit)
return Standard_True;
// (2) si l'ecart en distance est de l'ordre du gabarit
if (Abs(evoldist) < Gabarit) {
// (2.1) si le gain en angle est important on garde
if (evolangle > 0.5)
return Standard_True;
// (2.2) si la variation d'angle est moderee on evalue
// une fonction de penalite
if (Penalite(angle, dist/Gabarit) < Penalite(AngleMax, Dist/Gabarit) )
return Standard_True;
}
return Standard_False;
}

View File

@@ -0,0 +1,85 @@
-- File: GeomFill_SimpleBound.cdl
-- Created: Fri Nov 3 14:42:34 1995
-- Author: Laurent BOURESCHE
-- <lbo@phylox>
---Copyright: Matra Datavision 1995
class SimpleBound from GeomFill inherits Boundary from GeomFill
---Purpose: Defines a 3d curve as a boundary for a
-- GeomFill_ConstrainedFilling algorithm.
-- This curve is unattached to an existing surface.D
uses
Pnt from gp,
Vec from gp,
Function from Law,
HCurve from Adaptor3d
is
Create(Curve : HCurve from Adaptor3d;
Tol3d : Real from Standard;
Tolang : Real from Standard)
returns mutable SimpleBound from GeomFill;
--- Purpose:
-- Constructs the boundary object defined by the 3d curve.
-- The surface to be built along this boundary will be in the
-- tolerance range defined by Tol3d.
-- This object is to be used as a boundary for a
-- GeomFill_ConstrainedFilling framework.
-- Dummy is initialized but has no function in this class.
-- Warning
-- Curve is an adapted curve, that is, an object which is an interface between:
-- - the services provided by a 3D curve from the package Geom
-- - and those required of the curve by the computation
-- algorithm which uses it.
-- The adapted curve is created in one of the following ways:
-- - First sequence:
-- Handle(Geom_Curve) myCurve = ... ;
-- Handle(GeomAdaptor_HCurve)
-- Curve = new
-- GeomAdaptor_HCurve(myCurve);
-- - Second sequence:
-- // Step 1
-- Handle(Geom_Curve) myCurve = ... ;
-- GeomAdaptor_Curve Crv (myCurve);
-- // Step 2
-- Handle(GeomAdaptor_HCurve)
-- Curve = new
-- GeomAdaptor_HCurve(Crv);
-- You use the second part of this sequence if you already
-- have the adapted curve Crv.
-- The boundary is then constructed with the Curve object:
-- Standard_Real Tol = ... ;
-- Standard_Real dummy = 0. ;
-- myBoundary = GeomFill_SimpleBound
-- (Curve,Tol,dummy);
Value(me;
U : Real from Standard)
returns Pnt from gp;
D1(me;
U : Real from Standard;
P : out Pnt from gp;
V : out Vec from gp) ;
Reparametrize(me : mutable;
First, Last : Real from Standard;
HasDF, HasDL : Boolean from Standard;
DF, DL : Real from Standard;
Rev : Boolean from Standard);
Bounds(me; First, Last : out Real from Standard);
IsDegenerated(me) returns Boolean from Standard;
fields
myC3d : HCurve from Adaptor3d;
myPar : Function from Law;
end SimpleBound;

View File

@@ -0,0 +1,97 @@
// File: GeomFill_SimpleBound.cxx
// Created: Fri Nov 3 15:23:16 1995
// Author: Laurent BOURESCHE
// <lbo@phylox>
#include <GeomFill_SimpleBound.ixx>
#include <Law_BSpFunc.hxx>
#include <Law.hxx>
//=======================================================================
//function : GeomFill_SimpleBound
//purpose :
//=======================================================================
GeomFill_SimpleBound::GeomFill_SimpleBound
(const Handle(Adaptor3d_HCurve)& Curve,
const Standard_Real Tol3d,
const Standard_Real Tolang) :
GeomFill_Boundary(Tol3d,Tolang), myC3d(Curve)
{
}
//=======================================================================
//function : Value
//purpose :
//=======================================================================
gp_Pnt GeomFill_SimpleBound::Value(const Standard_Real U) const
{
Standard_Real x = U;
if(!myPar.IsNull()) x = myPar->Value(U);
return myC3d->Value(x);
}
//=======================================================================
//function : D1
//purpose :
//=======================================================================
void GeomFill_SimpleBound::D1(const Standard_Real U,
gp_Pnt& P,
gp_Vec& V) const
{
Standard_Real x = U, dx = 1.;
if(!myPar.IsNull()) myPar->D1(U,x,dx);
myC3d->D1(x, P, V);
V.Multiply(dx);
}
//=======================================================================
//function : Reparametrize
//purpose :
//=======================================================================
void GeomFill_SimpleBound::Reparametrize(const Standard_Real First,
const Standard_Real Last,
const Standard_Boolean HasDF,
const Standard_Boolean HasDL,
const Standard_Real DF,
const Standard_Real DL,
const Standard_Boolean Rev)
{
Handle(Law_BSpline) curve = Law::Reparametrize(myC3d->Curve(),
First,Last,
HasDF,HasDL,DF,DL,
Rev,30);
myPar = new Law_BSpFunc();
(*((Handle_Law_BSpFunc*) &myPar))->SetCurve(curve);
}
//=======================================================================
//function : Bounds
//purpose :
//=======================================================================
void GeomFill_SimpleBound::Bounds(Standard_Real& First,
Standard_Real& Last) const
{
if(!myPar.IsNull()) myPar->Bounds(First,Last);
else {
First = myC3d->FirstParameter();
Last = myC3d->LastParameter();
}
}
//=======================================================================
//function : IsDegenerated
//purpose :
//=======================================================================
Standard_Boolean GeomFill_SimpleBound::IsDegenerated() const
{
return Standard_False;
}

View File

@@ -0,0 +1,104 @@
-- File: GeomFill_SnglrFunc.cdl
-- Created: Thu Feb 26 10:42:27 1998
-- Author: Roman BORISOV
-- <rbv@ecolox.nnov.matra-dtv.fr>
---Copyright: Matra Datavision 1998
private class SnglrFunc from GeomFill inherits Curve from Adaptor3d
---Purpose: to represent function C'(t)^C''(t)
uses
HCurve from Adaptor3d,
Shape from GeomAbs,
CurveType from GeomAbs,
Array1OfReal from TColStd,
Pnt from gp,
Vec from gp
raises
OutOfRange from Standard,
DomainError from Standard
is
Create(HC: HCurve from Adaptor3d)
returns SnglrFunc;
SetRatio(me:in out; Ratio : Real)
is static;
FirstParameter(me) returns Real
is redefined static;
LastParameter(me) returns Real
is redefined static;
NbIntervals(me: in out; S : Shape from GeomAbs) returns Integer
---Purpose: Returns the number of intervals for continuity
-- <S>. May be one if Continuity(me) >= <S>
is redefined static;
Intervals(me: in out; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is redefined static;
Value(me; U : Real) returns Pnt from gp
--- Purpose : Computes the point of parameter U on the curve.
is redefined static;
IsPeriodic(me) returns Boolean
is redefined static;
Period(me) returns Real
raises
DomainError from Standard -- if the curve is not periodic
is redefined static;
D0 (me; U : Real; P : out Pnt from gp)
--- Purpose : Computes the point of parameter U on the curve.
is redefined static;
D1 (me; U : Real; P : out Pnt from gp ; V : out Vec from gp)
--- Purpose : Computes the point of parameter U on the curve with its
-- first derivative.
raises
DomainError from Standard
--- Purpose : Raised if the continuity of the current interval
-- is not C1.
is redefined static;
D2 (me; U : Real; P : out Pnt from gp; V1, V2 : out Vec from gp)
--- Purpose :
-- Returns the point P of parameter U, the first and second
-- derivatives V1 and V2.
raises
DomainError from Standard
--- Purpose : Raised if the continuity of the current interval
-- is not C2.
is redefined static;
Resolution(me; R3d : Real) returns Real
---Purpose : Returns the parametric resolution corresponding
-- to the real space resolution <R3d>.
is redefined static;
GetType(me) returns CurveType from GeomAbs
---Purpose: Returns the type of the curve in the current
-- interval : Line, Circle, Ellipse, Hyperbola,
-- Parabola, BezierCurve, BSplineCurve, OtherCurve.
is redefined static;
fields
myHCurve: HCurve from Adaptor3d;
ratio : Real;
end SnglrFunc;

View File

@@ -0,0 +1,126 @@
// File: GeomFill_SnglrFunc.cxx
// Created: Thu Feb 26 11:21:25 1998
// Author: Roman BORISOV
// <rbv@ecolox.nnov.matra-dtv.fr>
#include <GeomFill_SnglrFunc.ixx>
#include <Precision.hxx>
GeomFill_SnglrFunc::GeomFill_SnglrFunc(const Handle(Adaptor3d_HCurve)& HC) :
myHCurve(HC), ratio(1)
{
}
void GeomFill_SnglrFunc::SetRatio(const Standard_Real Ratio)
{
ratio = Ratio;
}
Standard_Real GeomFill_SnglrFunc::FirstParameter() const
{
return myHCurve->FirstParameter();
}
Standard_Real GeomFill_SnglrFunc::LastParameter() const
{
return myHCurve->LastParameter();
}
Standard_Integer GeomFill_SnglrFunc::NbIntervals(const GeomAbs_Shape S)
{
#ifndef DEB
GeomAbs_Shape HCS=GeomAbs_C0;
#else
GeomAbs_Shape HCS;
#endif
switch(S) {
case GeomAbs_C0: HCS = GeomAbs_C2; break;
case GeomAbs_C1: HCS = GeomAbs_C3; break;
case GeomAbs_C2: HCS = GeomAbs_CN; break;
default: Standard_DomainError::Raise();
}
return myHCurve->NbIntervals(HCS);
}
void GeomFill_SnglrFunc::Intervals(TColStd_Array1OfReal& T,const GeomAbs_Shape S)
{
#ifndef DEB
GeomAbs_Shape HCS=GeomAbs_C0;
#else
GeomAbs_Shape HCS ;
#endif
switch(S) {
case GeomAbs_C0: HCS = GeomAbs_C2; break;
case GeomAbs_C1: HCS = GeomAbs_C3; break;
case GeomAbs_C2: HCS = GeomAbs_CN; break;
default: Standard_DomainError::Raise();
}
myHCurve->Intervals(T, HCS);
}
Standard_Boolean GeomFill_SnglrFunc::IsPeriodic() const
{
return myHCurve->IsPeriodic();
}
Standard_Real GeomFill_SnglrFunc::Period() const
{
return myHCurve->Period();
}
gp_Pnt GeomFill_SnglrFunc::Value(const Standard_Real U) const
{
gp_Pnt C;
gp_Vec DC, D2C;
myHCurve->D2(U, C, DC, D2C);
DC *= ratio;
return gp_Pnt(DC.Crossed(D2C).XYZ());
}
void GeomFill_SnglrFunc::D0(const Standard_Real U,gp_Pnt& P) const
{
gp_Pnt C;
gp_Vec DC, D2C;
myHCurve->D2(U, C, DC, D2C);
DC *= ratio;
P = gp_Pnt(DC.Crossed(D2C).XYZ());
}
void GeomFill_SnglrFunc::D1(const Standard_Real U,gp_Pnt& P,gp_Vec& V) const
{
gp_Pnt C;
gp_Vec DC, D2C, D3C;
myHCurve->D3(U, C, DC, D2C, D3C);
DC *= ratio;
P = gp_Pnt(DC.Crossed(D2C).XYZ());
V = DC.Crossed(D3C);
}
void GeomFill_SnglrFunc::D2(const Standard_Real U,gp_Pnt& P,gp_Vec& V1,gp_Vec& V2) const
{
gp_Pnt C;
gp_Vec DC, D2C, D3C, D4C;
myHCurve->D3(U, C, DC, D2C, D3C);
P = gp_Pnt(DC.Crossed(D2C).XYZ());
V1 = DC.Crossed(D3C);
D4C = myHCurve->DN(U, 4);
V2 = D2C.Crossed(D3C) + DC.Crossed(D4C);
P.ChangeCoord() *= ratio;
V1 *= ratio;
V2 *= ratio;
}
Standard_Real GeomFill_SnglrFunc::Resolution(const Standard_Real R3D) const
{
return Precision::Parametric(R3D);
}
GeomAbs_CurveType GeomFill_SnglrFunc::GetType() const
{
return GeomAbs_OtherCurve;
}

View File

@@ -0,0 +1,32 @@
-- File: GeomFill_Stretch.cdl
-- Created: Tue Sep 28 16:18:35 1993
-- Author: Bruno DUMORTIER
-- <dub@sdsun1>
---Copyright: Matra Datavision 1993
class Stretch from GeomFill inherits Filling from GeomFill
uses
Array1OfPnt from TColgp,
Array1OfReal from TColStd
is
Create;
Create(P1, P2, P3, P4 : Array1OfPnt from TColgp)
returns Stretch from GeomFill;
Create(P1, P2, P3, P4 : Array1OfPnt from TColgp;
W1, W2, W3, W4 : Array1OfReal from TColStd)
returns Stretch from GeomFill;
Init(me : in out;
P1, P2, P3, P4 : Array1OfPnt from TColgp)
is static;
Init(me : in out;
P1, P2, P3, P4 : Array1OfPnt from TColgp;
W1, W2, W3, W4 : Array1OfReal from TColStd)
is static;
end Stretch;

176
src/GeomFill/GeomFill_Stretch.cxx Executable file
View File

@@ -0,0 +1,176 @@
// File: GeomFill_Stretch.cxx
// Created: Tue Sep 28 17:58:37 1993
// Author: Bruno DUMORTIER
// <dub@sdsun1>
#include <GeomFill_Stretch.ixx>
#include <gp_Pnt.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColgp_HArray2OfPnt.hxx>
#include <TColStd_HArray2OfReal.hxx>
//=======================================================================
//function : GeomFill_Stretch
//purpose :
//=======================================================================
GeomFill_Stretch::GeomFill_Stretch()
{
}
//=======================================================================
//function : GeomFill_Stretch
//purpose :
//=======================================================================
GeomFill_Stretch::GeomFill_Stretch(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2,
const TColgp_Array1OfPnt& P3,
const TColgp_Array1OfPnt& P4)
{
Init(P1, P2, P3, P4);
}
//=======================================================================
//function : GeomFill_Stretch
//purpose :
//=======================================================================
GeomFill_Stretch::GeomFill_Stretch(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2,
const TColgp_Array1OfPnt& P3,
const TColgp_Array1OfPnt& P4,
const TColStd_Array1OfReal& W1,
const TColStd_Array1OfReal& W2,
const TColStd_Array1OfReal& W3,
const TColStd_Array1OfReal& W4)
{
Init(P1, P2, P3, P4, W1, W2, W3, W4);
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_Stretch::Init(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2,
const TColgp_Array1OfPnt& P3,
const TColgp_Array1OfPnt& P4)
{
Standard_DomainError_Raise_if
( P1.Length() != P3.Length() || P2.Length() != P4.Length()," ");
Standard_Integer NPolU = P1.Length();
Standard_Integer NPolV = P2.Length();
IsRational = Standard_False;
Standard_Real NU = NPolU - 1;
Standard_Real NV = NPolV - 1;
myPoles = new TColgp_HArray2OfPnt( 1, NPolU, 1, NPolV);
// The boundaries are not modified
Standard_Integer i,j,k;
for ( i=1; i<=NPolU; i++) {
myPoles->SetValue( i, 1 , P1(i));
myPoles->SetValue( i, NPolV, P3(i));
}
Standard_Real PU,PU1,PV,PV1;
for ( j=2; j<=NPolV-1; j++) {
PV = (j-1)/NV;
PV1 = 1 - PV;
myPoles->SetValue( 1 , j, P4(j));
myPoles->SetValue( NPolU, j, P2(j));
for ( i=2; i<=NPolU-1; i++) {
PU = (i-1)/NU;
PU1 = 1 - PU;
gp_Pnt P;
for (k=1; k<=3; k++) {
P.SetCoord(k,
PV1 * P1(i).Coord(k) + PV * P3(i).Coord(k) +
PU * P2(j).Coord(k) + PU1 * P4(j).Coord(k) -
( PU1 * PV1 * P1(1).Coord(k) +
PU * PV1 * P2(1).Coord(k) +
PU * PV * P3(NPolU).Coord(k) +
PU1 * PV * P4(NPolV).Coord(k) ) );
}
myPoles->SetValue(i,j,P);
}
}
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_Stretch::Init(const TColgp_Array1OfPnt& P1,
const TColgp_Array1OfPnt& P2,
const TColgp_Array1OfPnt& P3,
const TColgp_Array1OfPnt& P4,
const TColStd_Array1OfReal& W1,
const TColStd_Array1OfReal& W2,
const TColStd_Array1OfReal& W3,
const TColStd_Array1OfReal& W4)
{
Standard_DomainError_Raise_if
( W1.Length() != W3.Length() || W2.Length() != W4.Length()," ");
Standard_DomainError_Raise_if
( W1.Length() != P1.Length() ||
W2.Length() != P2.Length() ||
W3.Length() != P3.Length() ||
W4.Length() != P4.Length() , " ");
Init(P1,P2,P3,P4);
IsRational = Standard_True;
Standard_Integer NPolU = W1.Length();
Standard_Integer NPolV = W2.Length();
Standard_Real NU = NPolU - 1;
Standard_Real NV = NPolV - 1;
myWeights = new TColStd_HArray2OfReal( 1, NPolU, 1, NPolV);
// The boundaries are not modified
Standard_Integer i,j;
for ( i=1; i<=NPolU; i++) {
myWeights->SetValue( i, 1 , W1(i));
myWeights->SetValue( i, NPolV, W3(i));
}
Standard_Real PU,PU1,PV,PV1;
for ( j=2; j<=NPolV-1; j++) {
PV = (j-1)/NV;
PV1 = 1 - PV;
myWeights->SetValue( 1 , j, W4(j));
myWeights->SetValue( NPolU, j, W2(j));
for ( i=2; i<=NPolU-1; i++) {
PU = (i-1)/NU;
PU1 = 1 - PU;
Standard_Real W = 0.5 * ( PV1 * W1(i) + PV * W3(i) +
PU * W2(j) + PU1 * W4(j) );
// Standard_Real W = PV1 * W1(i) + PV * W3(i) +
// PU * W2(j) + PU1 * W4(j) -
// ( PU1 * PV1 * W1(1) +
// PU * PV1 * W2(1) +
// PU * PV * W3(NPolU) +
// PU1 * PV * W4(NPolV) );
myWeights->SetValue(i,j,W);
}
}
}

185
src/GeomFill/GeomFill_Sweep.cdl Executable file
View File

@@ -0,0 +1,185 @@
-- File: GeomFill_Sweep.cdl
-- Created: Thu Nov 20 16:05:06 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
class Sweep from GeomFill
---Purpose: Geometrical Sweep Algorithm
---Level: Advanced
uses
SectionLaw from GeomFill,
LocationLaw from GeomFill,
ApproxStyle from GeomFill,
Shape from GeomAbs,
Surface from Geom,
Curve from Geom2d,
HArray1OfCurve from TColGeom2d,
HArray2OfReal from TColStd
raises
NotDone,
OutOfRange,
ConstructionError
is
Create(Location : LocationLaw from GeomFill;
WithKpart : Boolean = Standard_True)
returns Sweep from GeomFill;
SetDomain(me : in out; First, Last : Real;
SectionFirst, SectionLast : Real);
---Purpose: Set parametric information
-- [<First>, <Last>] Sets the parametric bound of the
-- sweeping surface to build.
-- <SectionFirst>, <SectionLast> gives coresponding
-- bounds parameter on the section law of <First> and <Last>
--
-- V-Iso on Sweeping Surface S(u,v) is defined by
-- Location(v) and Section(w) where
-- w = SectionFirst + (v - First) / (Last-First)
-- * (SectionLast - SectionFirst)
--
-- By default w = v, and First and Last are given by
-- First and Last parameter stored in LocationLaw.
SetTolerance(me : in out;
Tol3d : Real;
BoundTol : Real = 1.0;
Tol2d : Real = 1.0e-5;
TolAngular : Real = 1.0);
---Purpose: Set Approximation Tolerance
-- Tol3d : Tolerance to surface approximation
-- Tol2d : Tolerance used to perform curve approximation
-- Normaly the 2d curve are approximated with a
-- tolerance given by the resolution method define in
-- <LocationLaw> but if this tolerance is too large Tol2d
-- is used.
-- TolAngular : Tolerance (in radian) to control the angle
-- beetween tangents on the section law and
-- tangent of iso-v on approximed surface
ExchangeUV(me)
---Purpose: returns true if sections are U-Iso
-- This can be produce in some cases when <WithKpart> is True.
returns Boolean from Standard
is static;
UReversed(me)
---Purpose: returns true if Parametrisation sens in U is inverse of
-- parametrisation sens of section (or of path if ExchangeUV)
returns Boolean from Standard
is static;
VReversed(me)
---Purpose: returns true if Parametrisation sens in V is inverse of
-- parametrisation sens of path (or of section if ExchangeUV)
returns Boolean from Standard
is static;
Build(me : in out;
Section : SectionLaw from GeomFill;
Methode : ApproxStyle = GeomFill_Location;
Continuity : Shape = GeomAbs_C2;
Degmax : Integer = 10;
Segmax : Integer = 30)
---Purpose: Build the Sweeep Surface
-- ApproxStyle defines Approximation Strategy
-- - GeomFill_Section : The composed Function : Location X Section
-- is directly approximed.
-- - GeomFill_Location : The location law is approximed, and the
-- SweepSurface is build algebric composition
-- of approximed location law and section law
-- This option is Ok, if Section.Surface() methode
-- is effective.
-- Continuity : The continuity in v waiting on the surface
-- Degmax : The maximum degree in v requiered on the surface
-- Segmax : The maximum number of span in v requiered on
-- the surface
--
-- raise If Domain are infinite or Profile not Setted.
raises ConstructionError;
Build2d(me:in out;
Continuity : Shape;
Degmax : Integer;
Segmax : Integer)
returns Boolean
is private;
BuildAll(me:in out;
Continuity : Shape;
Degmax : Integer;
Segmax : Integer)
returns Boolean
is private;
BuildProduct(me:in out;
Continuity : Shape;
Degmax : Integer;
Segmax : Integer)
returns Boolean
is private;
BuildKPart(me:in out)
returns Boolean
is private;
IsDone(me)
---Purpose: Tells if the Surface is Buildt.
returns Boolean;
ErrorOnSurface(me)
---Purpose: Gets the Approximation error.
returns Real;
ErrorOnRestriction(me; IsFirst : Boolean;
UError, VError : out Real)
---Purpose: Gets the Approximation error.
raises NotDone;
ErrorOnTrace(me; IndexOfTrace : Integer;
UError, VError : out Real)
---Purpose: Gets the Approximation error.
raises NotDone, OutOfRange;
Surface(me)
returns Surface from Geom
raises NotDone;
Restriction(me; IsFirst : Boolean)
returns Curve from Geom2d
raises NotDone;
NumberOfTrace(me)
returns Integer;
Trace(me; IndexOfTrace : Integer)
returns Curve from Geom2d
raises NotDone, OutOfRange;
fields
First, Last : Real;
SFirst, SLast: Real;
Tol3d, BoundTol, Tol2d, TolAngular : Real;
SError : Real;
myLoc : LocationLaw from GeomFill;
mySec : SectionLaw from GeomFill;
mySurface : Surface from Geom;
myCurve2d : HArray1OfCurve from TColGeom2d;
CError : HArray2OfReal from TColStd;
done : Boolean;
myExchUV : Boolean from Standard;
isUReversed : Boolean;
isVReversed : Boolean;
myKPart : Boolean from Standard;
end Sweep;

1069
src/GeomFill/GeomFill_Sweep.cxx Executable file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,207 @@
-- File: GeomFill_SweepFunction.cdl
-- Created: Thu Nov 20 18:55:05 1997
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1997
private class SweepFunction from GeomFill
inherits SweepFunction from Approx
---Purpose: Function to approximate by SweepApproximation from
-- Approx. To bulid general sweep Surface.
uses
SectionLaw from GeomFill,
LocationLaw from GeomFill,
Mat from gp,
Vec from gp,
Pnt from gp,
Shape from GeomAbs ,
Array1OfPnt from TColgp,
Array1OfVec from TColgp,
Array1OfPnt2d from TColgp,
Array1OfVec2d from TColgp,
Array1OfReal from TColStd,
Array1OfInteger from TColStd
raises
OutOfRange from Standard
is
Create(Section : SectionLaw from GeomFill;
Location : LocationLaw from GeomFill;
FirstParameter, FirstParameterOnS, RatioParameterOnS : Real)
returns SweepFunction from GeomFill;
--
-- To compute Sections and derivatives Sections
--
--
D0(me : mutable;
Param: Real;
First, Last : Real;
Poles : out Array1OfPnt from TColgp;
Poles2d : out Array1OfPnt2d from TColgp;
Weigths : out Array1OfReal from TColStd)
---Purpose: compute the section for v = param
returns Boolean is redefined;
D1(me : mutable;
Param: Real;
First, Last : Real;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
Poles2d : out Array1OfPnt2d from TColgp;
DPoles2d : out Array1OfVec2d from TColgp;
Weigths : out Array1OfReal from TColStd;
DWeigths : out Array1OfReal from TColStd)
---Purpose: compute the first derivative in v direction of the
-- section for v = param
returns Boolean
is redefined;
D2(me : mutable;
Param: Real;
First, Last : Real;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
D2Poles : out Array1OfVec from TColgp;
Poles2d : out Array1OfPnt2d from TColgp;
DPoles2d : out Array1OfVec2d from TColgp;
D2Poles2d : out Array1OfVec2d from TColgp;
Weigths : out Array1OfReal from TColStd;
DWeigths : out Array1OfReal from TColStd;
D2Weigths : out Array1OfReal from TColStd)
---Purpose: compute the second derivative in v direction of the
-- section for v = param
returns Boolean
is redefined;
--
-- General Information On The Function
--
Nb2dCurves(me)
---Purpose: get the number of 2d curves to approximate.
returns Integer is redefined;
SectionShape(me; NbPoles : out Integer from Standard;
NbKnots : out Integer from Standard;
Degree : out Integer from Standard)
---Purpose: get the format of an section
is redefined;
Knots(me; TKnots: out Array1OfReal from TColStd)
---Purpose: get the Knots of the section
is redefined;
Mults(me; TMults: out Array1OfInteger from TColStd)
---Purpose: get the Multplicities of the section
is redefined;
IsRational(me)
---Purpose: Returns if the section is rationnal or not
returns Boolean is redefined;
--
-- Mangement of continuity
--
NbIntervals(me; S : Shape from GeomAbs)
---Purpose: Returns the number of intervals for continuity
-- <S>. May be one if Continuity(me) >= <S>
returns Integer is redefined;
Intervals(me; T : in out Array1OfReal from TColStd;
S : Shape from GeomAbs)
---Purpose: Stores in <T> the parameters bounding the intervals
-- of continuity <S>.
--
-- The array must provide enough room to accomodate
-- for the parameters. i.e. T.Length() > NbIntervals()
raises
OutOfRange from Standard
is redefined;
SetInterval(me: mutable; First, Last: Real from Standard)
---Purpose: Sets the bounds of the parametric interval on
-- the function
-- This determines the derivatives in these values if the
-- function is not Cn.
is redefined;
--
-- To help computation of Tolerance
--
-- Evaluation of error, in 2d space, or on rational function, is
-- dificult. The folowing methodes can help
--
--
Resolution(me;
Index : Integer from Standard;
Tol : Real from Standard;
TolU, TolV : out Real from Standard)
---Purpose: Returns the resolutions in the sub-space 2d <Index>
-- This information is usfull to find an good tolerance in
-- 2d approximation.
-- Warning: Used only if Nb2dCurve > 0
is redefined;
GetTolerance(me;
BoundTol, SurfTol, AngleTol : Real;
Tol3d : out Array1OfReal)
---Purpose: Returns the tolerance to reach in approximation
-- to respecte
-- BoundTol error at the Boundary
-- AngleTol tangent error at the Boundary (in radian)
-- SurfTol error inside the surface.
is redefined;
SetTolerance(me : mutable; Tol3d, Tol2d : Real)
---Purpose: Is usfull, if (me) have to be run numerical
-- algorithme to perform D0, D1 or D2
is redefined;
BarycentreOfSurf(me)
---Purpose: Get the barycentre of Surface. An very poor
-- estimation is sufficent. This information is usefull
-- to perform well conditionned rational approximation.
-- Warning: Used only if <me> IsRational
returns Pnt from gp
is redefined;
MaximalSection(me) returns Real
---Purpose: Returns the length of the maximum section. This
-- information is usefull to perform well conditionned rational
-- approximation.
-- Warning: Used only if <me> IsRational
is redefined;
GetMinimalWeight(me; Weigths : out Array1OfReal from TColStd)
---Purpose: Compute the minimal value of weight for each poles
-- of all sections. This information is usefull to
-- perform well conditionned rational approximation.
-- Warning: Used only if <me> IsRational
is redefined;
fields
myLoc : LocationLaw from GeomFill;
mySec : SectionLaw from GeomFill;
myf : Real;
myfOnS : Real;
myRatio: Real;
M, DM, D2M : Mat from gp;
V, DV, D2V : Vec from gp;
end SweepFunction;

View File

@@ -0,0 +1,384 @@
// File: GeomFill_SweepFunction.cxx
// Created: Fri Nov 21 15:18:48 1997
// Author: Philippe MANGIN
// <pmn@sgi29>
#ifndef DEB
#define No_Standard_RangeError
#define No_Standard_OutOfRange
#define No_Standard_DimensionError
#endif
#include <GeomFill_SweepFunction.ixx>
#include <TColStd_SequenceOfReal.hxx>
#include <GeomLib.hxx>
#include <Precision.hxx>
//=======================================================================
//function : GeomFill_SweepFunction
//purpose :
//=======================================================================
GeomFill_SweepFunction::
GeomFill_SweepFunction(const Handle(GeomFill_SectionLaw)& Section,
const Handle(GeomFill_LocationLaw)& Location,
const Standard_Real FirstParameter,
const Standard_Real FirstParameterOnS,
const Standard_Real RatioParameterOnS)
{
myLoc = Location;
mySec = Section;
myf = FirstParameter;
myfOnS = FirstParameterOnS;
myRatio = RatioParameterOnS;
}
//=======================================================================
//function : D0
//purpose :
//=======================================================================
Standard_Boolean GeomFill_SweepFunction::D0(const Standard_Real Param,
const Standard_Real,
const Standard_Real,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfPnt2d& Poles2d,
TColStd_Array1OfReal& Weigths)
{
Standard_Integer ii, L;
Standard_Boolean Ok;
Standard_Real T = myfOnS + (Param - myf) * myRatio;
L = Poles.Length();
Ok = myLoc->D0(Param, M, V, Poles2d);
if (!Ok) return Ok;
Ok = mySec->D0(T, Poles, Weigths);
if (!Ok) return Ok;
for (ii=1; ii<=L; ii++) {
gp_XYZ& aux = Poles(ii).ChangeCoord();
aux *= M;
aux += V.XYZ();
}
return Standard_True;
}
//=======================================================================
//function : D1
//purpose :
//=======================================================================
Standard_Boolean GeomFill_SweepFunction::D1(const Standard_Real Param,
const Standard_Real,
const Standard_Real,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfVec& DPoles,
TColgp_Array1OfPnt2d& Poles2d,
TColgp_Array1OfVec2d& DPoles2d,
TColStd_Array1OfReal& Weigths,
TColStd_Array1OfReal& DWeigths)
{
Standard_Integer ii, L;
Standard_Boolean Ok;
Standard_Real T = myfOnS + (Param - myf) * myRatio;
gp_XYZ PPrim;
L = Poles.Length();
Ok = myLoc->D1(Param, M, V, DM, DV, Poles2d, DPoles2d);
if (!Ok) return Ok;
Ok = mySec->D1(T, Poles, DPoles, Weigths, DWeigths);
if (!Ok) return Ok;
for (ii=1; ii<=L; ii++) {
PPrim = DPoles(ii).XYZ();
gp_XYZ& P = Poles(ii).ChangeCoord();
PPrim *= myRatio;
DWeigths(ii) *= myRatio;
PPrim *= M;
PPrim += DM*P;
PPrim += DV.XYZ();
DPoles(ii).SetXYZ(PPrim);
P *= M;
P += V.XYZ();
}
return Standard_True;
}
//=======================================================================
//function : D2
//purpose :
//=======================================================================
Standard_Boolean GeomFill_SweepFunction::D2(const Standard_Real Param,
const Standard_Real,
const Standard_Real ,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfVec& DPoles,
TColgp_Array1OfVec& D2Poles,
TColgp_Array1OfPnt2d& Poles2d,
TColgp_Array1OfVec2d& DPoles2d,
TColgp_Array1OfVec2d& D2Poles2d,
TColStd_Array1OfReal& Weigths,
TColStd_Array1OfReal& DWeigths,
TColStd_Array1OfReal& D2Weigths)
{
Standard_Integer ii, L;
Standard_Boolean Ok;
Standard_Real T = myfOnS + (Param - myf) * myRatio;
Standard_Real squareratio = myRatio*myRatio;
L = Poles.Length();
Ok = myLoc->D2(Param, M, V, DM, DV, D2M, D2V,
Poles2d, DPoles2d, D2Poles2d);
if (!Ok) return Ok;
Ok = mySec->D2(T, Poles, DPoles, D2Poles,
Weigths, DWeigths, D2Weigths);
if (!Ok) return Ok;
for (ii=1; ii<=L; ii++) {
gp_XYZ PSecn = D2Poles(ii).XYZ();
gp_XYZ PPrim = DPoles(ii).XYZ();
PPrim *= myRatio;
DWeigths(ii) *= myRatio;
PSecn *= squareratio;
D2Weigths(ii) *= squareratio;
gp_XYZ& P = Poles(ii).ChangeCoord();
PSecn *= M;
PSecn += 2*(DM*PPrim);
PSecn += D2M*P;
PSecn += D2V.XYZ();
D2Poles(ii).SetXYZ(PSecn);
PPrim *= M;
PPrim += DM*P;
PPrim += DV.XYZ();
DPoles(ii).SetXYZ(PPrim);
P *= M;
P += V.XYZ();
}
return Standard_True;
}
//=======================================================================
//function : Nb2dCurves
//purpose :
//=======================================================================
Standard_Integer GeomFill_SweepFunction::Nb2dCurves() const
{
return myLoc->Nb2dCurves();
}
//=======================================================================
//function : SectionShape
//purpose :
//=======================================================================
void GeomFill_SweepFunction::SectionShape(Standard_Integer& NbPoles,
Standard_Integer& NbKnots,
Standard_Integer& Degree) const
{
mySec->SectionShape(NbPoles, NbKnots, Degree);
}
//=======================================================================
//function : Knots
//purpose :
//=======================================================================
void GeomFill_SweepFunction::Knots(TColStd_Array1OfReal& TKnots) const
{
mySec->Knots(TKnots);
}
//=======================================================================
//function : Mults
//purpose :
//=======================================================================
void GeomFill_SweepFunction::Mults(TColStd_Array1OfInteger& TMults) const
{
mySec->Mults(TMults);
}
//=======================================================================
//function : IsRational
//purpose :
//=======================================================================
Standard_Boolean GeomFill_SweepFunction::IsRational() const
{
return mySec->IsRational();
}
//=======================================================================
//function : NbIntervals
//purpose :
//=======================================================================
Standard_Integer GeomFill_SweepFunction::NbIntervals(const GeomAbs_Shape S) const
{
Standard_Integer Nb_Sec, Nb_Loc;
Nb_Sec = mySec->NbIntervals(S);
Nb_Loc = myLoc->NbIntervals(S);
if (Nb_Sec==1) {
return Nb_Loc;
}
else if (Nb_Loc==1) {
return Nb_Sec;
}
TColStd_Array1OfReal IntS(1, Nb_Sec+1);
TColStd_Array1OfReal IntL(1, Nb_Loc+1);
TColStd_SequenceOfReal Inter;
Standard_Real T;
Standard_Integer ii;
mySec->Intervals(IntS, S);
for (ii=1; ii<=Nb_Sec+1; ii++) {
T = (IntS(ii) - myfOnS) / myRatio + myf;
IntS(ii) = T;
}
myLoc->Intervals(IntL, S);
GeomLib::FuseIntervals( IntS, IntL, Inter, Precision::PConfusion()*0.99);
return Inter.Length()-1;
}
//=======================================================================
//function : Intervals
//purpose :
//=======================================================================
void GeomFill_SweepFunction::Intervals(TColStd_Array1OfReal& T,const GeomAbs_Shape S) const
{
Standard_Integer Nb_Sec, Nb_Loc, ii;
Nb_Sec = mySec->NbIntervals(S);
Nb_Loc = myLoc->NbIntervals(S);
if (Nb_Sec==1) {
myLoc->Intervals(T, S);
return;
}
else if (Nb_Loc==1) {
Standard_Real t;
mySec->Intervals(T, S);
for (ii=1; ii<=Nb_Sec+1; ii++) {
t = (T(ii) - myfOnS) / myRatio + myf;
T(ii) = t;
}
return;
}
TColStd_Array1OfReal IntS(1, Nb_Sec+1);
TColStd_Array1OfReal IntL(1, Nb_Loc+1);
TColStd_SequenceOfReal Inter;
Standard_Real t;
mySec->Intervals(IntS, S);
for (ii=1; ii<=Nb_Sec+1; ii++) {
t = (IntS(ii) - myfOnS) / myRatio + myf;
IntS(ii) = t;
}
myLoc->Intervals(IntL, S);
GeomLib::FuseIntervals(IntS, IntL, Inter, Precision::PConfusion()*0.99);
for (ii=1; ii<=Inter.Length(); ii++)
T(ii) = Inter(ii);
}
//=======================================================================
//function : SetInterval
//purpose :
//=======================================================================
void GeomFill_SweepFunction::SetInterval(const Standard_Real First,
const Standard_Real Last)
{
Standard_Real uf, ul;
myLoc->SetInterval(First, Last);
uf = myf + (First - myf) * myRatio;
ul = myf + (Last - myf) * myRatio;
mySec->SetInterval(uf, ul);
}
//=======================================================================
//function :
//purpose :
//=======================================================================
void GeomFill_SweepFunction::GetTolerance(const Standard_Real BoundTol,
const Standard_Real SurfTol,
const Standard_Real AngleTol,
TColStd_Array1OfReal& Tol3d) const
{
mySec->GetTolerance( BoundTol, SurfTol, AngleTol, Tol3d);
}
//=======================================================================
//function : Resolution
//purpose :
//=======================================================================
void GeomFill_SweepFunction::Resolution(const Standard_Integer Index,
const Standard_Real Tol,
Standard_Real& TolU,
Standard_Real& TolV)const
{
myLoc->Resolution(Index, Tol, TolU, TolV);
}
//=======================================================================
//function :
//purpose :
//=======================================================================
void GeomFill_SweepFunction::SetTolerance(const Standard_Real Tol3d,
const Standard_Real Tol2d)
{
mySec->SetTolerance(Tol3d, Tol2d);
myLoc->SetTolerance(Tol3d, Tol2d);
}
//=======================================================================
//function :
//purpose :
//=======================================================================
gp_Pnt GeomFill_SweepFunction::BarycentreOfSurf() const
{
gp_Pnt Bary;
gp_Vec Translate;
gp_Mat M;
Bary = mySec->BarycentreOfSurf();
myLoc->GetAverageLaw(M, Translate);
Bary.ChangeCoord() *= M;
Bary.ChangeCoord() += Translate.XYZ();
return Bary;
}
//=======================================================================
//function :
//purpose :
//=======================================================================
Standard_Real GeomFill_SweepFunction::MaximalSection() const
{
Standard_Real L = mySec->MaximalSection();
L *= myLoc->GetMaximalNorm();
return L;
}
//=======================================================================
//function :
//purpose :
//=======================================================================
void GeomFill_SweepFunction::GetMinimalWeight(TColStd_Array1OfReal& Weigths) const
{
mySec->GetMinimalWeight(Weigths);
}

View File

@@ -0,0 +1,181 @@
-- File: GeomFill_SweepSectionGenerator.cdl
-- Created: Mon Feb 28 14:00:01 1994
-- Author: Bruno DUMORTIER
-- <dub@fuegox>
---Copyright: Matra Datavision 1994
class SweepSectionGenerator from GeomFill
---Purpose: class for instantiation of AppBlend.
-- evaluate the sections of a sweep surface.
uses
HCurve from Adaptor3d,
Ax1 from gp,
Vec from gp,
Trsf from gp,
Array1OfPnt from TColgp,
Array1OfVec from TColgp,
Array1OfPnt2d from TColgp,
Array1OfVec2d from TColgp,
Array1OfReal from TColStd,
Array1OfInteger from TColStd,
Curve from Geom,
BSplineCurve from Geom,
SequenceOfCurve from TColGeom,
SequenceOfTrsf from GeomFill
raises
RangeError from Standard
is
Create returns SweepSectionGenerator from GeomFill;
Create( Path : Curve from Geom;
Radius : Real from Standard)
---Purpose: Create a sweept surface with a constant radius.
returns SweepSectionGenerator from GeomFill;
Create( Path : Curve from Geom;
FirstSect : Curve from Geom )
---Purpose: Create a sweept surface with a constant section
returns SweepSectionGenerator from GeomFill;
Create( Path : Curve from Geom;
FirstSect : Curve from Geom;
LastSect : Curve from Geom )
---Purpose: Create a sweept surface with an evolving section
-- The section evoluate from First to Last Section
returns SweepSectionGenerator from GeomFill;
Create( Path : Curve from Geom;
Curve1 : Curve from Geom;
Curve2 : Curve from Geom;
Radius : Real from Standard )
---Purpose: Create a pipe with a constant radius with 2
-- guide-line.
returns SweepSectionGenerator from GeomFill;
Create( Path : HCurve from Adaptor3d;
Curve1 : HCurve from Adaptor3d;
Curve2 : HCurve from Adaptor3d;
Radius : Real from Standard )
---Purpose: Create a pipe with a constant radius with 2
-- guide-line.
returns SweepSectionGenerator from GeomFill;
Init( me : in out;
Path : Curve from Geom;
Radius : Real from Standard)
is static;
Init( me : in out;
Path : Curve from Geom;
FirstSect : Curve from Geom)
is static;
Init( me : in out;
Path : Curve from Geom;
FirstSect : Curve from Geom;
LastSect : Curve from Geom)
is static;
Init( me : in out;
Path : Curve from Geom;
Curve1 : Curve from Geom;
Curve2 : Curve from Geom;
Radius : Real from Standard)
is static;
Init( me : in out;
Path : HCurve from Adaptor3d;
Curve1 : HCurve from Adaptor3d;
Curve2 : HCurve from Adaptor3d;
Radius : Real from Standard )
is static;
Perform( me : in out;
Polynomial : Boolean from Standard = Standard_False)
is static;
GetShape(me; NbPoles : out Integer from Standard;
NbKnots : out Integer from Standard;
Degree : out Integer from Standard;
NbPoles2d : out Integer from Standard)
is static;
Knots(me; TKnots: out Array1OfReal from TColStd)
is static;
Mults(me; TMults: out Array1OfInteger from TColStd)
is static;
NbSections(me)
---C++: inline
returns Integer from Standard
is static;
Section(me; P : Integer from Standard;
Poles : out Array1OfPnt from TColgp;
DPoles : out Array1OfVec from TColgp;
Poles2d : out Array1OfPnt2d from TColgp;
DPoles2d : out Array1OfVec2d from TColgp;
Weigths : out Array1OfReal from TColStd;
DWeigths : out Array1OfReal from TColStd)
---Purpose: Used for the first and last section
-- The method returns Standard_True if the derivatives
-- are computed, otherwise it returns Standard_False.
returns Boolean from Standard
is static;
Section(me; P : Integer from Standard;
Poles : out Array1OfPnt from TColgp;
Poles2d : out Array1OfPnt2d from TColgp;
Weigths : out Array1OfReal from TColStd)
is static;
Transformation(me; Index : Integer from Standard)
returns Trsf from gp
---C++: return const &
raises
RangeError from Standard
---Purpose: raised if <Index> not in the range [1,NbSections()]
is static;
Parameter(me; P: Integer)
---Purpose: Returns the parameter of <P>, to impose it for the
-- approximation.
returns Real from Standard
is static;
fields
myPath : BSplineCurve from Geom;
myFirstSect : BSplineCurve from Geom;
myLastSect : BSplineCurve from Geom;
myAdpPath : HCurve from Adaptor3d;
myAdpFirstSect : HCurve from Adaptor3d;
myAdpLastSect : HCurve from Adaptor3d;
myCircPathAxis : Ax1 from gp;
myRadius : Real from Standard;
myIsDone : Boolean from Standard;
myNbSections : Integer from Standard;
myTrsfs : SequenceOfTrsf from GeomFill;
myType : Integer from Standard;
myPolynomial : Boolean from Standard;
end SweepSectionGenerator;

View File

@@ -0,0 +1,698 @@
// File: GeomFill_SweepSectionGenerator.cxx
// Created: Mon Feb 28 14:14:53 1994
// Author: Bruno DUMORTIER
// <dub@fuegox>
#include <GeomFill_SweepSectionGenerator.ixx>
#include <GeomFill_Profiler.hxx>
#include <gp_Dir.hxx>
#include <gp_Vec.hxx>
#include <gp_Trsf.hxx>
#include <gp_Pnt.hxx>
#include <gp_Ax3.hxx>
#include <gp_Ax2.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <Geom_Circle.hxx>
#include <GeomConvert.hxx>
#include <Precision.hxx>
#include <ElCLib.hxx>
#include <GeomAdaptor.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GCPnts_QuasiUniformDeflection.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <stdio.h>
#ifdef DRAW
#include <DrawTrSurf.hxx>
#endif
#ifdef DEB
static Standard_Boolean Affich = Standard_False;
static Standard_Integer NbSECTIONS = 0;
#endif
//=======================================================================
//function : GeomFill_SweepSectionGenerator
//purpose :
//=======================================================================
GeomFill_SweepSectionGenerator::GeomFill_SweepSectionGenerator()
{
myIsDone = Standard_False;
}
//=======================================================================
//function : GeomFill_SweepSectionGenerator
//purpose :
//=======================================================================
GeomFill_SweepSectionGenerator::GeomFill_SweepSectionGenerator
(const Handle(Geom_Curve)& Path,
const Standard_Real Radius)
{
Init(Path,Radius);
}
//=======================================================================
//function : GeomFill_SweepSectionGenerator
//purpose :
//=======================================================================
GeomFill_SweepSectionGenerator::GeomFill_SweepSectionGenerator
(const Handle(Geom_Curve)& Path,
const Handle(Geom_Curve)& FirstSect)
{
Init(Path,FirstSect);
}
//=======================================================================
//function : GeomFill_SweepSectionGenerator
//purpose :
//=======================================================================
GeomFill_SweepSectionGenerator::GeomFill_SweepSectionGenerator
(const Handle(Geom_Curve)& Path,
const Handle(Geom_Curve)& FirstSect,
const Handle(Geom_Curve)& LastSect )
{
Init(Path,FirstSect,LastSect);
}
//=======================================================================
//function : GeomFill_SweepSectionGenerator
//purpose :
//=======================================================================
GeomFill_SweepSectionGenerator::GeomFill_SweepSectionGenerator
(const Handle(Adaptor3d_HCurve)& Path,
const Handle(Adaptor3d_HCurve)& Curve1,
const Handle(Adaptor3d_HCurve)& Curve2,
const Standard_Real Radius)
{
Init(Path,Curve1,Curve2,Radius);
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_SweepSectionGenerator::Init(const Handle(Geom_Curve)& Path,
const Standard_Real Radius)
{
myIsDone = Standard_False;
myRadius = Radius;
GeomAdaptor_Curve ThePath(Path);
if (ThePath.GetType() == GeomAbs_Circle) {
myCircPathAxis = ThePath.Circle().Axis();
myType = 4;
}
else myType = 1;
if ( Path->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
myPath = Handle(Geom_BSplineCurve)::DownCast(Path->Copy());
}
else {
myPath = GeomConvert::CurveToBSplineCurve(Path);
}
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_SweepSectionGenerator::Init
(const Handle(Geom_Curve)& Path,
const Handle(Geom_Curve)& FirstSect)
{
myIsDone = Standard_False;
myRadius = 0;
GeomAdaptor_Curve ThePath(Path);
if (ThePath.GetType() == GeomAbs_Circle) {
myCircPathAxis = ThePath.Circle().Axis();
myType = 5;
}
else myType = 2;
if ( Path->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
myPath = Handle(Geom_BSplineCurve)::DownCast(Path->Copy());
}
else {
myPath = GeomConvert::CurveToBSplineCurve(Path);
}
if ( FirstSect->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
myFirstSect = Handle(Geom_BSplineCurve)::DownCast(FirstSect->Copy());
}
else {
// JAG
myFirstSect = GeomConvert::CurveToBSplineCurve(FirstSect,
Convert_QuasiAngular);
}
if ( myFirstSect->IsPeriodic()) myFirstSect->SetNotPeriodic();
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_SweepSectionGenerator::Init
(const Handle(Geom_Curve)& Path,
const Handle(Geom_Curve)& FirstSect,
const Handle(Geom_Curve)& LastSect )
{
myIsDone = Standard_False;
myRadius = 0;
GeomAdaptor_Curve ThePath(Path);
if (ThePath.GetType() == GeomAbs_Circle) {
myCircPathAxis = ThePath.Circle().Axis();
myType = 6;
}
else myType = 3;
if ( Path->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
myPath = Handle(Geom_BSplineCurve)::DownCast(Path->Copy());
}
else {
myPath = GeomConvert::CurveToBSplineCurve(Path);
}
// JAG
if ( FirstSect->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
myFirstSect = Handle(Geom_BSplineCurve)::DownCast(FirstSect->Copy());
}
else {
myFirstSect = GeomConvert::CurveToBSplineCurve(FirstSect,
Convert_QuasiAngular);
}
if ( LastSect->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
myLastSect = Handle(Geom_BSplineCurve)::DownCast(LastSect->Copy());
}
else {
myLastSect = GeomConvert::CurveToBSplineCurve(LastSect,
Convert_QuasiAngular);
}
if ( myFirstSect->IsPeriodic()) myFirstSect->SetNotPeriodic();
if ( myLastSect->IsPeriodic()) myLastSect->SetNotPeriodic();
// JAG
GeomFill_Profiler Profil;
Profil.AddCurve(myFirstSect);
Profil.AddCurve(myLastSect);
Profil.Perform(Precision::Confusion());
myFirstSect = Handle(Geom_BSplineCurve)::DownCast(Profil.Curve(1));
myLastSect = Handle(Geom_BSplineCurve)::DownCast(Profil.Curve(2));
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomFill_SweepSectionGenerator::Init
(const Handle(Adaptor3d_HCurve)& Path,
const Handle(Adaptor3d_HCurve)& Curve1,
const Handle(Adaptor3d_HCurve)& Curve2,
const Standard_Real Radius)
{
myIsDone = Standard_False;
myRadius = Radius;
myType = 0;
Handle(Geom_Curve) CC = GeomAdaptor::MakeCurve(Path->Curve());
myPath = GeomConvert::CurveToBSplineCurve(CC);
myAdpPath = Path;
myAdpFirstSect = Curve1;
myAdpLastSect = Curve2;
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void GeomFill_SweepSectionGenerator::Perform(const Standard_Boolean Polynomial)
{
myPolynomial = Polynomial;
// eval myNbSections.
#ifdef DEB
Standard_Integer Deg = myPath->Degree();
#else
myPath->Degree();
#endif
Standard_Integer NSpans = myPath->NbKnots()-1;
myNbSections = 21 * NSpans;
Standard_Real U;
Standard_Real U1 = myPath->FirstParameter();
Standard_Real U2 = myPath->LastParameter();
GCPnts_QuasiUniformDeflection Samp;
// Calcul de la longueur approximative de la courbe
GeomAdaptor_Curve AdpPath(myPath);
gp_Pnt P1 = AdpPath.Value(U1);
gp_Pnt P2 = AdpPath.Value((U1+U2)/2.);
gp_Pnt P3 = AdpPath.Value(U2);
Standard_Real Length =
P1.Distance(P2) + P2.Distance(P3);
Standard_Real Fleche = 1.e-5 * Length;
Samp.Initialize(AdpPath,Fleche);
if ( Samp.IsDone() && (Samp.NbPoints() > myNbSections) ) {
myNbSections = Samp.NbPoints();
}
// the transformations are calculate on differents points of <myPath>
// corresponding to the path parameter uniformly reparted.
Standard_Real DeltaU = (U2-U1)/(Standard_Real)(myNbSections-1);
TColStd_Array1OfReal Parameters(1,myNbSections);
// Parameters(1) = U1;
// for (Standard_Integer i = 2; i < myNbSections; i++) {
// Parameters(i) = U1 + (i-1) * DeltaU;
// }
// Parameters(myNbSections) = U2;
Parameters(1) = 0.;
for (Standard_Integer i = 2; i < myNbSections; i++) {
Parameters(i) = (i-1) * DeltaU;
}
Parameters(myNbSections) = U2 - U1;
gp_Vec D1Ref, D1;
gp_Pnt PRef , P;
gp_Trsf TR, cumulTR, Trans;
myPath->D1( U1, PRef, D1Ref);
if ( ( myType == 1) || (myType == 4) ) {
// We create a circle with radius <myRadius>. This axis is create with
// main direction <DRef> (first derivate vector of <myPath> on the first
// point <PRef> ). This circle is, after transform to BSpline curve,
// put in <myFirstSect>.
gp_Ax2 CircleAxis (PRef,D1Ref);
/*
Handle(Geom_Circle) Circ = new Geom_Circle( CircleAxis, myRadius);
myFirstSect = GeomConvert::CurveToBSplineCurve(Circ);
// le cercle est segmente car AppBlend_AppSurf ne gere
// pas les courbes periodiques.
myFirstSect->Segment(0., 2.*PI);
*/
Handle(Geom_TrimmedCurve) Circ =
new Geom_TrimmedCurve(new Geom_Circle( CircleAxis, myRadius),
0., 2.*PI);
myFirstSect = GeomConvert::CurveToBSplineCurve(Circ,Convert_QuasiAngular);
}
if (myType <= 3 && myType >=1 ) {
for (Standard_Integer i = 2; i <= myNbSections; i++) {
U = Parameters(i) + U1;
if (i == myNbSections) U = U2;
myPath->D1( U, P, D1);
// Eval the translation between the (i-1) section and the i-th.
Trans.SetTranslation(PRef, P);
gp_Trsf Rot;
if (! D1Ref.IsParallel(D1, Precision::Angular())) {
// Eval the Rotation between (i-1) section and the i-th.
Rot.SetRotation(gp_Ax1(P, gp_Dir(D1Ref^D1)),
D1Ref.AngleWithRef(D1, D1Ref^D1));
}
else
if (D1Ref.IsOpposite(D1, Precision::Angular()))
cout <<"Que fais-je ???? " << endl;
// TR is the transformation between (i-1) section and the i-th.
TR = Rot * Trans;
// cumulTR is the transformation between <myFirstSec> and
// the i-th section.
cumulTR = TR * cumulTR;
myTrsfs.Append(cumulTR);
PRef = P;
D1Ref = D1;
}
}
else if ( myType != 0) {
for (Standard_Integer i = 2; i<= myNbSections; i++) {
cumulTR.SetRotation(myCircPathAxis, Parameters(i));
myTrsfs.Append(cumulTR);
}
}
myIsDone = Standard_True;
}
//=======================================================================
//function : GetShape
//purpose :
//=======================================================================
void GeomFill_SweepSectionGenerator::GetShape
(Standard_Integer& NbPoles,
Standard_Integer& NbKnots,
Standard_Integer& Degree,
Standard_Integer& NbPoles2d) const
{
/*
if ( myType == 1) {
NbPoles = 7;
NbKnots = 4;
Degree = 2;
}
else {
*/
if ( myType != 0) {
NbPoles = myFirstSect->NbPoles();
NbKnots = myFirstSect->NbKnots();
Degree = myFirstSect->Degree();
}
else { // myType == 0
NbPoles = 7;
NbKnots = 2;
Degree = 6;
}
NbPoles2d = 0;
}
//=======================================================================
//function : Knots
//purpose :
//=======================================================================
void GeomFill_SweepSectionGenerator::Knots(TColStd_Array1OfReal& TKnots) const
{
/*
if (myType == 1) {
Standard_Real U = 2.*PI/3.;
for ( Standard_Integer i = 1; i <= 4; i++)
TKnots(i) = ( i-1) * U;
}
else {
*/
if (myType !=0) {
myFirstSect->Knots(TKnots);
}
else {
TKnots(1) = 0.;
TKnots(2) = 1.;
}
// }
}
//=======================================================================
//function : Mults
//purpose :
//=======================================================================
void GeomFill_SweepSectionGenerator::Mults(TColStd_Array1OfInteger& TMults)
const
{
/*
if ( myType == 1) {
TMults( 1) = TMults( 4) = 3;
TMults( 2) = TMults( 3) = 2;
}
else {
*/
if ( myType != 0) {
myFirstSect->Multiplicities(TMults);
}
else {
TMults( 1) = TMults( 2) = 7;
}
// }
}
//=======================================================================
//function : Section
//purpose :
//=======================================================================
Standard_Boolean GeomFill_SweepSectionGenerator::Section
(const Standard_Integer P,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfVec& DPoles,
TColgp_Array1OfPnt2d& Poles2d,
TColgp_Array1OfVec2d& , //DPoles2d,
TColStd_Array1OfReal& Weigths,
TColStd_Array1OfReal& DWeigths
) const
{
Section( P, Poles, Poles2d, Weigths);
// pour les tuyaux sur aretes pour l'instant on ne calcule pas les derivees
if ( myType == 0 ) return Standard_False; // a voir pour mieux.
// calcul des derivees sur la surface
// on calcule les derivees en approximant le path au voisinage du point
// P(u) par le cercle osculateur au path .
// calcul du cercle osculateur.
Standard_Real U;
if ( P == 1) {
U = myPath->FirstParameter();
}
else if ( P == myNbSections ) {
U = myPath->LastParameter();
}
else
return Standard_False;
gp_Vec D1, D2;
gp_Pnt Pt;
myPath->D2(U,Pt,D1,D2);
Standard_Real l = D1.Magnitude();
if ( l < Epsilon(1.))
return Standard_False;
gp_Dir T = D1;
Standard_Real m = D2.Dot(T);
gp_Vec D = D2 - m * T;
Standard_Real c = D.Magnitude() / (l*l);
if ( c < Epsilon(1.)) {
// null curvature : equivalent to a translation of the section
for (Standard_Integer i = 1; i <= myFirstSect->NbPoles(); i++) {
DPoles(i) = D1;
}
}
else {
gp_Dir N = D;
gp_Pnt Q = Pt.Translated( (1./c) * gp_Vec(N));
Standard_Real x, y;
gp_Vec V;
for ( Standard_Integer i = 1; i <= myFirstSect->NbPoles(); i++) {
V = gp_Vec(Q, Poles(i));
x = V * gp_Vec(T);
y = V * gp_Vec(N);
DPoles(i) = x * gp_Vec(N) - y * gp_Vec(T);
if ( DPoles(i).Magnitude() > Epsilon(1.)) {
DPoles(i).Normalize();
DPoles(i) *= Sqrt( x*x + y*y);
}
}
}
for ( Standard_Integer i = 1; i <= myFirstSect->NbPoles(); i++) {
DWeigths(i) = 0.;
}
return Standard_True;
}
//=======================================================================
//function : Section
//purpose :
//=======================================================================
void GeomFill_SweepSectionGenerator::Section
(const Standard_Integer P,
TColgp_Array1OfPnt& Poles,
TColgp_Array1OfPnt2d& , //Poles2d,
TColStd_Array1OfReal& Weigths) const
{
if (myType != 0) {
myFirstSect->Poles(Poles);
myFirstSect->Weights(Weigths);
gp_Trsf cumulTR;
if (P > 1) {
cumulTR = myTrsfs(P - 1);
// <cumulTR> transform <myFirstSect> to the P ieme Section. In fact
// each points of the array <poles> will be transformed.
if ( (myType == 3 ) || (myType == 6) ){
for (Standard_Integer i = 1; i <= myFirstSect->NbPoles(); i++) {
Poles(i).SetXYZ( (myNbSections - P) * myFirstSect->Pole(i).XYZ() +
(P - 1) * myLastSect->Pole(i).XYZ() );
Poles(i).SetXYZ( Poles(i).XYZ() / (myNbSections - 1));
Weigths(i) = (myNbSections - P) * myFirstSect->Weight(i) +
(P - 1) * myLastSect->Weight(i);
Weigths(i) /= myNbSections - 1;
}
}
for (Standard_Integer i = 1; i<=Poles.Length(); i++)
Poles(i).Transform(cumulTR);
}
#ifdef DRAW
if ( Affich) {
//POP pour NT
// char name[100];
char* name = new char[100];
sprintf(name,"SECTION_%d",++NbSECTIONS);
DrawTrSurf::Set(name,myFirstSect->Transformed(cumulTR));
}
#endif
}
else {
Standard_Real Coef = (P -1. ) / ( myNbSections - 1.);
Standard_Real U =
( 1- Coef) * myAdpPath->FirstParameter() +
Coef * myAdpPath->LastParameter();
gp_Pnt PPath = myAdpPath->Value(U);
Standard_Real Alpha = U - myAdpPath->FirstParameter();
Alpha /= myAdpPath->LastParameter() - myAdpPath->FirstParameter();
Standard_Real U1 =
( 1- Alpha) * myAdpFirstSect->FirstParameter() +
Alpha * myAdpFirstSect->LastParameter();
gp_Pnt P1 = myAdpFirstSect->Value(U1);
Standard_Real U2 =
( 1- Alpha) * myAdpLastSect->FirstParameter() +
Alpha * myAdpLastSect->LastParameter();
gp_Pnt P2 = myAdpLastSect->Value(U2);
gp_Ax2 Axis;
Standard_Real Angle;
if ( P1.Distance(P2) < Precision::Confusion()) {
Angle = 0.;
}
else {
Axis = gp_Ax2(PPath,
gp_Vec(PPath,P1) ^ gp_Vec(PPath,P2),
gp_Vec(PPath,P1));
Angle = ElCLib::CircleParameter(Axis,P2);
}
#ifdef DEB
if (Standard_False) {
gp_Vec dummyD1 = myAdpPath->DN(U,1);
gp_Vec dummyTg = Axis.Direction();
Standard_Real Cos = dummyD1.Dot(dummyTg);
if ( Cos > 0.) cout << "+" ;
else cout << "-" ;
}
#endif
if ( Angle < Precision::Angular()) {
for ( Standard_Integer i = 1; i <= Poles.Upper(); i++) {
Poles(i) = P1;
Weigths(i) = 1;
}
}
else {
Handle(Geom_Circle) Circ =
new Geom_Circle( Axis, myRadius);
Handle(Geom_TrimmedCurve) CT =
new Geom_TrimmedCurve(Circ, 0., Angle);
Handle(Geom_BSplineCurve) BS;
if ( myPolynomial)
BS = GeomConvert::CurveToBSplineCurve( CT, Convert_Polynomial);
else
BS = GeomConvert::CurveToBSplineCurve( CT, Convert_QuasiAngular);
#ifdef DRAW
if ( Affich) {
// POP pour NT
// char name[100];
char* name = new char[100];
sprintf(name,"SECTION_%d",++NbSECTIONS);
DrawTrSurf::Set(name,BS);
}
#endif
BS->Poles(Poles);
BS->Weights(Weigths);
}
}
}
//=======================================================================
//function : Transformation
//purpose :
//=======================================================================
const gp_Trsf& GeomFill_SweepSectionGenerator::Transformation
(const Standard_Integer Index) const
{
if (Index > myTrsfs.Length())
Standard_RangeError::Raise
("GeomFill_SweepSectionGenerator::Transformation");
return myTrsfs(Index);
}
//=======================================================================
//function : Parameter
//purpose :
//=======================================================================
Standard_Real GeomFill_SweepSectionGenerator::Parameter
(const Standard_Integer P) const
{
if (P == 1) {
return myPath->FirstParameter();
}
else if (P == myNbSections) {
return myPath->LastParameter();
}
else {
Standard_Real U1 = myPath->FirstParameter();
Standard_Real U2 = myPath->LastParameter();
Standard_Real prm = ((myNbSections-P)*U1 + (P-1)*U2)/
(Standard_Real)(myNbSections-1);
return prm;
}
}

View File

@@ -0,0 +1,14 @@
// File: GeomFill_SweepSectionGenerator.lxx
// Created: Thu Apr 14 10:36:58 1994
// Author: Bruno DUMORTIER
// <dub@fuegox>
//=======================================================================
//function : NbSections
//purpose :
//=======================================================================
inline Standard_Integer GeomFill_SweepSectionGenerator::NbSections() const
{
return myNbSections;
}

View File

@@ -0,0 +1,61 @@
-- File: BlendFunc_Tensor.cdl
-- Created: Thu Dec 5 09:27:33 1996
-- Author: Philippe MANGIN
-- <pmn@sgi29>
---Copyright: Matra Datavision 1996
class Tensor from GeomFill
---Purpose: used to store the "gradient of gradient"
uses
Array1OfReal from TColStd,
Vector from math,
Matrix from math
raises DimensionError from Standard,
RangeError from Standard
is
Create(NbRow, NbCol, NbMat : Integer)
returns Tensor;
Init(me : in out; InitialValue: Real)
---Purpose:Initialize all the elements of a Tensor to InitialValue.
is static;
Value(me; Row, Col, Mat: Integer)
---Purpose: accesses (in read or write mode) the value of index <Row>,
-- <Col> and <Mat> of a Tensor.
-- An exception is raised if <Row>, <Col> or <Mat> are not
-- in the correct range.
---C++: alias operator()
---C++: return const &
---C++: inline
returns Real
is static;
ChangeValue(me : in out; Row, Col, Mat: Integer)
---Purpose: accesses (in read or write mode) the value of index <Row>,
-- <Col> and <Mat> of a Tensor.
-- An exception is raised if <Row>, <Col> or <Mat> are not
-- in the correct range.
---C++: alias operator()
---C++: return &
---C++: inline
returns Real
is static;
Multiply(me; Right: Vector; Product:out Matrix)
raises DimensionError
is static;
fields
Tab : Array1OfReal;
nbrow : Integer;
nbcol : Integer;
nbmat : Integer;
nbmtcl : Integer;
end ;

Some files were not shown because too many files have changed in this diff Show More