SplineBasisfunction::SplineBasisfunction (TColStd_Array1OfReal& vKnots, TColStd_Array1OfInteger& vMults, int iSize, int iOrder) : _vKnotVector(0,iSize-1) { int sum = 0; for (int h=vMults.Lower(); h<=vMults.Upper(); h++) sum += vMults(h); if (vKnots.Length() != vMults.Length() || iSize != sum) { // Werfe Exception Standard_ConstructionError::Raise("BSplineBasis"); } int k=0; for (int i=vMults.Lower(); i<=vMults.Upper(); i++) { for (int j=0; j<vMults(i); j++) { _vKnotVector(k) = vKnots(i); k++; } } _iOrder = iOrder; }
void BSplineBasis::AllBasisFunctions(double fParam, TColStd_Array1OfReal& vFuncVals) { if (vFuncVals.Length() != _iOrder) Standard_RangeError::Raise("BSplineBasis"); int iIndex = FindSpan(fParam); TColStd_Array1OfReal zaehler_left(1,_iOrder-1); TColStd_Array1OfReal zaehler_right(1,_iOrder-1); vFuncVals(0) = 1.0f; for (int j=1; j<_iOrder; j++) { zaehler_left(j) = fParam - _vKnotVector(iIndex+1-j); zaehler_right(j) = _vKnotVector(iIndex+j) - fParam; double saved = 0.0f; for (int r=0; r<j; r++) { double tmp = vFuncVals(r)/(zaehler_right(r+1) + zaehler_left(j-r)); vFuncVals(r) = saved + zaehler_right(r+1)*tmp; saved = zaehler_left(j-r)*tmp; } vFuncVals(j) = saved; } }
void SplineBasisfunction::SetKnots(TColStd_Array1OfReal& vKnots, int iOrder) { if (_vKnotVector.Length() != vKnots.Length()) Standard_RangeError::Raise("BSplineBasis"); _vKnotVector = vKnots; _iOrder = iOrder; }
//======================================================================= //function : SortShapes //purpose : //======================================================================= void GEOMUtils::SortShapes (TopTools_ListOfShape& SL, const Standard_Boolean isOldSorting) { #ifdef STD_SORT_ALGO std::vector<TopoDS_Shape> aShapesVec; aShapesVec.reserve(SL.Extent()); TopTools_ListIteratorOfListOfShape it (SL); for (; it.More(); it.Next()) { aShapesVec.push_back(it.Value()); } SL.Clear(); CompareShapes shComp (isOldSorting); std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp); //std::sort(aShapesVec.begin(), aShapesVec.end(), shComp); std::vector<TopoDS_Shape>::const_iterator anIter = aShapesVec.begin(); for (; anIter != aShapesVec.end(); ++anIter) { SL.Append(*anIter); } #else // old implementation Standard_Integer MaxShapes = SL.Extent(); TopTools_Array1OfShape aShapes (1,MaxShapes); TColStd_Array1OfInteger OrderInd(1,MaxShapes); TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z; TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z; // Computing of CentreOfMass Standard_Integer Index; GProp_GProps GPr; gp_Pnt GPoint; TopTools_ListIteratorOfListOfShape it(SL); for (Index=1; it.More(); Index++) { TopoDS_Shape S = it.Value(); SL.Remove( it ); // == it.Next() aShapes(Index) = S; OrderInd.SetValue (Index, Index); if (S.ShapeType() == TopAbs_VERTEX) { GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S )); Length.SetValue( Index, (Standard_Real) S.Orientation()); } else { // BEGIN: fix for Mantis issue 0020842 if (isOldSorting) { BRepGProp::LinearProperties (S, GPr); } else { if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) { BRepGProp::LinearProperties (S, GPr); } else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) { BRepGProp::SurfaceProperties(S, GPr); } else { BRepGProp::VolumeProperties(S, GPr); } } // END: fix for Mantis issue 0020842 GPoint = GPr.CentreOfMass(); Length.SetValue(Index, GPr.Mass()); } MidXYZ.SetValue(Index, GPoint.X()*999.0 + GPoint.Y()*99.0 + GPoint.Z()*0.9); //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl; } // Sorting Standard_Integer aTemp; Standard_Boolean exchange, Sort = Standard_True; Standard_Real tol = Precision::Confusion(); while (Sort) { Sort = Standard_False; for (Index=1; Index < MaxShapes; Index++) { exchange = Standard_False; Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1)); Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1)); if ( dMidXYZ >= tol ) { // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1)) // << " d: " << dMidXYZ << endl; exchange = Standard_True; } else if ( Abs(dMidXYZ) < tol && dLength >= tol ) { // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1)) // << " d: " << dLength << endl; exchange = Standard_True; } else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol && aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) { // PAL17233 // equal values possible on shapes such as two halves of a sphere and // a membrane inside the sphere Bnd_Box box1,box2; BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 ); if ( box1.IsVoid() ) continue; BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 ); Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent(); if ( dSquareExtent >= tol ) { // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl; exchange = Standard_True; } else if ( Abs(dSquareExtent) < tol ) { Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2; box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9; box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9; //exchange = val1 > val2; if ((val1 - val2) >= tol) { exchange = Standard_True; } //cout << "box: " << val1<<" > "<<val2 << endl; } } if (exchange) { // cout << "exchange " << Index << " & " << Index+1 << endl; aTemp = OrderInd(Index); OrderInd(Index) = OrderInd(Index+1); OrderInd(Index+1) = aTemp; Sort = Standard_True; } } } for (Index=1; Index <= MaxShapes; Index++) SL.Append( aShapes( OrderInd(Index) )); #endif }
SplineBasisfunction::SplineBasisfunction(TColStd_Array1OfReal& vKnots, int iOrder) : _vKnotVector(0,vKnots.Length()-1) { _vKnotVector = vKnots; _iOrder = iOrder; }
void BSplineBasis::GenerateRootsAndWeights(TColStd_Array1OfReal& vRoots, TColStd_Array1OfReal& vWeights) { int iSize = vRoots.Length(); //Nullstellen der Legendre-Polynome und die zugeh. Gewichte if (iSize == 1) { vRoots(0) = 0.0f; vWeights(0) = 2.0f; } else if (iSize == 2) { vRoots(0) = 0.57735f; vWeights(0) = 1.0f; vRoots(1) = -vRoots(0); vWeights(1) = vWeights(0); } else if (iSize == 4) { vRoots(0) = 0.33998f; vWeights(0) = 0.65214f; vRoots(1) = 0.86113f; vWeights(1) = 0.34785f; vRoots(2) = -vRoots(0); vWeights(2) = vWeights(0); vRoots(3) = -vRoots(1); vWeights(3) = vWeights(1); } else if (iSize == 6) { vRoots(0) = 0.23861f; vWeights(0) = 0.46791f; vRoots(1) = 0.66120f; vWeights(1) = 0.36076f; vRoots(2) = 0.93246f; vWeights(2) = 0.17132f; vRoots(3) = -vRoots(0); vWeights(3) = vWeights(0); vRoots(4) = -vRoots(1); vWeights(4) = vWeights(1); vRoots(5) = -vRoots(2); vWeights(5) = vWeights(2); } else if (iSize == 8) { vRoots(0) = 0.18343f; vWeights(0) = 0.36268f; vRoots(1) = 0.52553f; vWeights(1) = 0.31370f; vRoots(2) = 0.79666f; vWeights(2) = 0.22238f; vRoots(3) = 0.96028f; vWeights(3) = 0.10122f; vRoots(4) = -vRoots(0); vWeights(4) = vWeights(0); vRoots(5) = -vRoots(1); vWeights(5) = vWeights(1); vRoots(6) = -vRoots(2); vWeights(6) = vWeights(2); vRoots(7) = -vRoots(3); vWeights(7) = vWeights(3); } else if (iSize == 10) { vRoots(0) = 0.14887f; vWeights(0) = 0.29552f; vRoots(1) = 0.43339f; vWeights(1) = 0.26926f; vRoots(2) = 0.67940f; vWeights(2) = 0.21908f; vRoots(3) = 0.86506f; vWeights(3) = 0.14945f; vRoots(4) = 0.97390f; vWeights(4) = 0.06667f; vRoots(5) = -vRoots(0); vWeights(5) = vWeights(0); vRoots(6) = -vRoots(1); vWeights(6) = vWeights(1); vRoots(7) = -vRoots(2); vWeights(7) = vWeights(2); vRoots(8) = -vRoots(3); vWeights(8) = vWeights(3); vRoots(9) = -vRoots(4); vWeights(9) = vWeights(4); } else { vRoots(0) = 0.12523f; vWeights(0) = 0.24914f; vRoots(1) = 0.36783f; vWeights(1) = 0.23349f; vRoots(2) = 0.58731f; vWeights(2) = 0.20316f; vRoots(3) = 0.76990f; vWeights(3) = 0.16007f; vRoots(4) = 0.90411f; vWeights(4) = 0.10693f; vRoots(5) = 0.98156f; vWeights(5) = 0.04717f; vRoots(6) = -vRoots(0); vWeights(6) = vWeights(0); vRoots(7) = -vRoots(1); vWeights(7) = vWeights(1); vRoots(8) = -vRoots(2); vWeights(8) = vWeights(2); vRoots(9) = -vRoots(3); vWeights(9) = vWeights(3); vRoots(10)= -vRoots(4); vWeights(10)= vWeights(4); vRoots(11)= -vRoots(5); vWeights(11)= vWeights(5); } }
void BSplineBasis::DerivativesOfBasisFunction(int iIndex, int iMaxDer, double fParam, TColStd_Array1OfReal& Derivat) { int iMax = iMaxDer; if (Derivat.Length() != iMax+1) Standard_RangeError::Raise("BSplineBasis"); //k-te Ableitungen (k>Grad) sind Null if (iMax >= _iOrder) { for (int i=_iOrder; i<=iMaxDer; i++) Derivat(i) = 0.0f; iMax = _iOrder - 1; } TColStd_Array1OfReal ND(0, iMax); int p = _iOrder-1; math_Matrix N(0,p,0,p); double saved; // falls Wert außerhalb Intervall, dann Funktionswert und alle Ableitungen gleich Null if (fParam < _vKnotVector(iIndex) || fParam >= _vKnotVector(iIndex+p+1)) { for (int k=0; k<=iMax; k++) Derivat(k) = 0.0f; return; } // Berechne die Basisfunktionen der Ordnung 1 for (int j=0; j<_iOrder; j++) { if (fParam >= _vKnotVector(iIndex+j) && fParam < _vKnotVector(iIndex+j+1)) N(j,0) = 1.0f; else N(j,0) = 0.0f; } // Berechne Dreieckstabelle der Funktionswerte for (int k=1; k<_iOrder; k++) { if (N(0,k-1) == 0.0f) saved = 0.0f; else saved = ((fParam - _vKnotVector(iIndex))*N(0,k-1))/(_vKnotVector(iIndex+k)-_vKnotVector(iIndex)); for (int j=0; j<p-k+1; j++) { double Tleft = _vKnotVector(iIndex+j+1); double Tright = _vKnotVector(iIndex+j+k+1); if (N(j+1,k-1) == 0.0) { N(j,k) = saved; saved = 0.0f; } else { double tmp = N(j+1,k-1)/(Tright-Tleft); N(j,k) = saved + (Tright-fParam)*tmp; saved = (fParam-Tleft)*tmp; } } } // Funktionswert Derivat(0) = N(0,p); // Berechne aus der Dreieckstabelle die Ableitungen for (int k=1; k<=iMax; k++) { for (int j=0; j<=k; j++) { // Lade (p-k)-te Spalte ND(j) = N(j,p-k); } for (int jj=1; jj<=k; jj++) { if (ND(0) == 0.0f) saved = 0.0f; else saved = ND(0)/(_vKnotVector(iIndex+p-k+jj) - _vKnotVector(iIndex)); for (int j=0; j<k-jj+1; j++) { double Tleft = _vKnotVector(iIndex+j+1); double Tright = _vKnotVector(iIndex+j+p-k+jj+1); if (ND(j+1) == 0.0f) { ND(j) = (p-k+jj)*saved; saved = 0.0f; } else { double tmp = ND(j+1)/(Tright-Tleft); ND(j) = (p-k+jj)*(saved-tmp); saved = tmp; } } } Derivat(k) = ND(0); //k-te Ableitung } return; }
void HeeksDxfRead::OnReadSpline(struct SplineData& sd) { bool closed = (sd.flag & 1) != 0; bool periodic = (sd.flag & 2) != 0; bool rational = (sd.flag & 4) != 0; // bool planar = (sd.flag & 8) != 0; // bool linear = (sd.flag & 16) != 0; SplineData sd_copy = sd; if(closed) { // add some more control points sd_copy.control_points += 3; //for(int i = 0; i<3; i++ //sd_copy.controlx } TColgp_Array1OfPnt control (1,/*closed ? sd.controlx.size() + 1:*/sd.controlx.size()); TColStd_Array1OfReal weight (1,sd.controlx.size()); std::list<double> knoto; std::list<int> multo; std::list<double>::iterator ity = sd.controly.begin(); std::list<double>::iterator itz = sd.controlz.begin(); std::list<double>::iterator itw = sd.weight.begin(); unsigned i=1; //int i=1; for(std::list<double>::iterator itx = sd.controlx.begin(); itx!=sd.controlx.end(); ++itx) { gp_Pnt pnt(*itx,*ity,*itz); control.SetValue(i,pnt); if(sd.weight.empty()) weight.SetValue(i,1); else { weight.SetValue(i,*itw); ++itw; } ++i; ++ity; ++itz; } i=1; double last_knot = -1; for(std::list<double>::iterator it = sd.knot.begin(); it!=sd.knot.end(); ++it) { if(*it != last_knot) { knoto.push_back(*it); multo.push_back(1); i++; } else { int temp = multo.back(); multo.pop_back(); multo.push_back(temp+1); } last_knot = *it; } TColStd_Array1OfReal knot (1, knoto.size()); TColStd_Array1OfInteger mult (1, knoto.size()); std::list<int>::iterator itm = multo.begin(); i = 1; for(std::list<double>::iterator it = knoto.begin(); it!=knoto.end(); ++it) { knot.SetValue(i,*it); int m = *itm; if(closed && (i == 1 || i == knoto.size()))m = 1; mult.SetValue(i, m); ++itm; ++i; } OnReadSpline(control, weight, knot, mult, sd.degree, periodic, rational); }