1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-05 18:16:23 +03:00
occt/src/GeomFill/GeomFill_Profiler.cxx
ski 9775fa6110 0026937: Eliminate NO_CXX_EXCEPTION macro support
Macro NO_CXX_EXCEPTION was removed from code.
Method Raise() was replaced by explicit throw statement.
Method Standard_Failure::Caught() was replaced by normal C++mechanism of exception transfer.
Method Standard_Failure::Caught() is deprecated now.
Eliminated empty constructors.
Updated samples.
Eliminate empty method ChangeValue from NCollection_Map class.
Removed not operable methods from NCollection classes.
2017-02-02 16:35:54 +03:00

371 lines
11 KiB
C++

// Created on: 1994-02-17
// Created by: Bruno DUMORTIER
// Copyright (c) 1994-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BSplCLib.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_Conic.hxx>
#include <Geom_Curve.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <GeomConvert.hxx>
#include <GeomConvert_ApproxCurve.hxx>
#include <GeomFill_Profiler.hxx>
#include <Standard_DomainError.hxx>
#include <StdFail_NotDone.hxx>
//=======================================================================
//function : UnifyByInsertingAllKnots
//purpose :
//=======================================================================
void UnifyByInsertingAllKnots(TColGeom_SequenceOfCurve& theCurves,
const Standard_Real PTol)
{
// inserting in the first curve the knot-vector of all the others.
Handle(Geom_BSplineCurve) C = Handle(Geom_BSplineCurve)::DownCast(theCurves(1));
Standard_Integer i;
for ( i = 2; i <= theCurves.Length(); i++) {
Handle(Geom_BSplineCurve) Ci =
Handle(Geom_BSplineCurve)::DownCast(theCurves(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 <= theCurves.Length(); i++) {
Handle(Geom_BSplineCurve) Ci =
Handle(Geom_BSplineCurve)::DownCast(theCurves(i));
Ci->InsertKnots(NewKnots, NewMults, PTol, Standard_False);
}
// essai : tentative mise des poids sur chaque section a une moyenne 1
for ( i = 1; i <= theCurves.Length(); i++) {
Handle(Geom_BSplineCurve) Ci =
Handle(Geom_BSplineCurve)::DownCast(theCurves(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
}
//=======================================================================
//function : UnifyBySettingMiddleKnots
//purpose :
//=======================================================================
void UnifyBySettingMiddleKnots(TColGeom_SequenceOfCurve& theCurves)
{
Standard_Integer i, j;
Handle(Geom_BSplineCurve) C = Handle(Geom_BSplineCurve)::DownCast(theCurves(1));
Standard_Integer NbKnots = C->NbKnots();
Standard_Real ULast = C->Knot(C->LastUKnotIndex());
Standard_Real UFirst = C->Knot(C->FirstUKnotIndex());
//Set middle values of knots
TColStd_Array1OfReal NewKnots(1, NbKnots);
NewKnots(1) = UFirst;
NewKnots(NbKnots) = ULast;
for (j = 2; j < NbKnots; j++)
{
Standard_Real aMidKnot = 0.;
for (i = 1; i <= theCurves.Length(); i++)
{
Handle(Geom_BSplineCurve) Ctemp = Handle(Geom_BSplineCurve)::DownCast(theCurves(i));
aMidKnot += Ctemp->Knot(j);
}
aMidKnot /= theCurves.Length();
NewKnots(j) = aMidKnot;
}
for (i = 1; i <= theCurves.Length(); i++)
{
Handle(Geom_BSplineCurve) Cres = Handle(Geom_BSplineCurve)::DownCast(theCurves(i));
Cres->SetKnots(NewKnots);
}
}
//=======================================================================
//function : GeomFill_Profiler
//purpose :
//=======================================================================
GeomFill_Profiler::GeomFill_Profiler()
{
myIsDone = Standard_False;
myIsPeriodic = Standard_True;
}
//=======================================================================
GeomFill_Profiler::~GeomFill_Profiler()
{
}
//=======================================================================
//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)::DownCast (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);
}
TColGeom_SequenceOfCurve theCurves;
for (i = 1; i <= mySequence.Length(); i++)
theCurves.Append(Handle(Geom_Curve)::DownCast(mySequence(i)->Copy()));
UnifyByInsertingAllKnots(theCurves, PTol);
Standard_Boolean Unified = Standard_True;
Standard_Integer theNbKnots = (Handle(Geom_BSplineCurve)::DownCast(theCurves(1)))->NbKnots();
for (i = 2; i <= theCurves.Length(); i++)
if ((Handle(Geom_BSplineCurve)::DownCast(theCurves(i)))->NbKnots() != theNbKnots)
{
Unified = Standard_False;
break;
}
if (Unified)
mySequence = theCurves;
else
UnifyBySettingMiddleKnots(mySequence);
myIsDone = Standard_True;
}
//=======================================================================
//function : Degree
//purpose :
//=======================================================================
Standard_Integer GeomFill_Profiler::Degree() const
{
if ( !myIsDone)
throw StdFail_NotDone("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)
throw StdFail_NotDone("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)
throw StdFail_NotDone("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)
throw StdFail_NotDone("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)
throw StdFail_NotDone("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)
throw StdFail_NotDone("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);
}