void CylinderFit::ProjectToCylinder() { Base::Vector3f cBase(GetBase()); Base::Vector3f cAxis(GetAxis()); for (std::list< Base::Vector3f >::iterator it = _vPoints.begin(); it != _vPoints.end(); ++it) { Base::Vector3f& cPnt = *it; if (cPnt.DistanceToLine(cBase, cAxis) > 0) { Base::Vector3f proj; cBase.ProjectToPlane(cPnt, cAxis, proj); Base::Vector3f diff = cPnt - proj; diff.Normalize(); cPnt = proj + diff * _fRadius; } else { // Point is on the cylinder axis, so it can be moved in // any direction perpendicular to the cylinder axis Base::Vector3f cMov(cPnt); do { float x = ((float)rand() / (float)RAND_MAX); float y = ((float)rand() / (float)RAND_MAX); float z = ((float)rand() / (float)RAND_MAX); cMov.Move(x,y,z); } while (cMov.DistanceToLine(cBase, cAxis) == 0); Base::Vector3f proj; cMov.ProjectToPlane(cPnt, cAxis, proj); Base::Vector3f diff = cPnt - proj; diff.Normalize(); cPnt = proj + diff * _fRadius; } } }
/*! \brief Calculate angle between two vectors Dependancies: Vector3D definitions and routines */ double Routines::CalcAngle(Base::Vector3f a,Base::Vector3f b,Base::Vector3f c) { Base::Vector3f First = a - b; Base::Vector3f Second = c - b; Base::Vector3f Third = c - a; //double test1 = First.Length(), test2 = Second.Length(), test3 = Third.Length(); double UpperTerm = (First.Length() * First.Length()) + (Second.Length() *Second.Length()) - (Third.Length() * Third.Length() ); double LowerTerm = 2 * First.Length() * Second.Length() ; double ang = acos( UpperTerm / LowerTerm ); return ang; }
float CylinderFit::GetDistanceToCylinder(const Base::Vector3f &rcPoint) const { float fResult = FLOAT_MAX; if (_bIsFitted) fResult = rcPoint.DistanceToLine(_vBase, _vAxis) - _fRadius; return fResult; }
void PlaneFit::Dimension(float& length, float& width) const { const Base::Vector3f& bs = _vBase; const Base::Vector3f& ex = _vDirU; const Base::Vector3f& ey = _vDirV; Base::BoundBox3f bbox; std::list<Base::Vector3f>::const_iterator cIt; for (cIt = _vPoints.begin(); cIt != _vPoints.end(); ++cIt) { Base::Vector3f pnt = *cIt; pnt.TransformToCoordinateSystem(bs, ex, ey); bbox.Add(pnt); } length = bbox.MaxX - bbox.MinX; width = bbox.MaxY - bbox.MinY; }
void MeshObject::offsetSpecial(float fSize, float zmax, float zmin) { std::vector<Base::Vector3f> normals = _kernel.CalcVertexNormals(); unsigned int i = 0; // go through all the vertex normals for (std::vector<Base::Vector3f>::iterator It= normals.begin();It != normals.end();It++,i++) { Base::Vector3f Pnt = _kernel.GetPoint(i); if (Pnt.z < zmax && Pnt.z > zmin) { Pnt.z = 0; _kernel.MovePoint(i,Pnt.Normalize() * fSize); } else { // and move each mesh point in the normal direction _kernel.MovePoint(i,It->Normalize() * fSize); } } }
void MeshAlgos::offsetSpecial(MeshCore::MeshKernel* Mesh, float fSize, float zmax, float zmin) { std::vector<Base::Vector3f> normals = Mesh->CalcVertexNormals(); unsigned int i = 0; // go throug all the Vertex normales for(std::vector<Base::Vector3f>::iterator It= normals.begin();It != normals.end();++It,i++) { Base::Vector3f Pnt = Mesh->GetPoint(i); if(Pnt.z < zmax && Pnt.z > zmin) { Pnt.z = 0; Mesh->MovePoint(i,Pnt.Normalize() * fSize); }else // and move each mesh point in the normal direction Mesh->MovePoint(i,It->Normalize() * fSize); } }
void AbstractPolygonTriangulator::PostProcessing(const std::vector<Base::Vector3f>& points) { // For a good approximation we should have enough points, i.e. for 9 parameters // for the fit function we should have at least 50 points. unsigned int uMinPts = 50; PolynomialFit polyFit; Base::Vector3f bs((float)_inverse[0][3], (float)_inverse[1][3], (float)_inverse[2][3]); Base::Vector3f ex((float)_inverse[0][0], (float)_inverse[1][0], (float)_inverse[2][0]); Base::Vector3f ey((float)_inverse[0][1], (float)_inverse[1][1], (float)_inverse[2][1]); for (std::vector<Base::Vector3f>::const_iterator it = points.begin(); it != points.end(); ++it) { Base::Vector3f pt = *it; pt.TransformToCoordinateSystem(bs, ex, ey); polyFit.AddPoint(pt); } if (polyFit.CountPoints() >= uMinPts && polyFit.Fit() < FLOAT_MAX) { for (std::vector<Base::Vector3f>::iterator pt = _newpoints.begin(); pt != _newpoints.end(); ++pt) pt->z = (float)polyFit.Value(pt->x, pt->y); } }
void Approximation::Convert( const Wm4::Vector3<double>& Wm4, Base::Vector3f& pt) { pt.Set( (float)Wm4.X(), (float)Wm4.Y(), (float)Wm4.Z() ); }
void ViewProviderFemConstraintGear::updateData(const App::Property* prop) { Fem::ConstraintGear* pcConstraint = static_cast<Fem::ConstraintGear*>(this->getObject()); // Gets called whenever a property of the attached object changes if (strcmp(prop->getName(),"BasePoint") == 0) { if (pcConstraint->Height.getValue() > Precision::Confusion()) { // Remove and recreate the symbol pShapeSep->removeAllChildren(); Base::Vector3f base = pcConstraint->BasePoint.getValue(); Base::Vector3f axis = pcConstraint->Axis.getValue(); Base::Vector3f direction = pcConstraint->DirectionVector.getValue(); if (direction.Length() < Precision::Confusion()) direction = Base::Vector3f(0,1,0); float radius = pcConstraint->Radius.getValue(); float dia = pcConstraint->Diameter.getValue(); if (dia < 2 * radius) dia = 2 * radius; float angle = pcConstraint->ForceAngle.getValue() / 180 * M_PI; SbVec3f b(base.x, base.y, base.z); SbVec3f ax(axis.x, axis.y, axis.z); SbVec3f dir(direction.x, direction.y, direction.z); //Base::Console().Error("DirectionVector: %f, %f, %f\n", direction.x, direction.y, direction.z); createPlacement(pShapeSep, b, SbRotation(SbVec3f(0,1,0), ax)); pShapeSep->addChild(createCylinder(pcConstraint->Height.getValue() * 0.8, dia/2)); createPlacement(pShapeSep, SbVec3f(dia/2 * sin(angle), 0, dia/2 * cos(angle)), SbRotation(ax, dir)); pShapeSep->addChild(createArrow(dia/2, dia/8)); } } else if (strcmp(prop->getName(),"Diameter") == 0) { if (pShapeSep->getNumChildren() > 0) { // Change the symbol Base::Vector3f axis = pcConstraint->Axis.getValue(); Base::Vector3f direction = pcConstraint->DirectionVector.getValue(); if (direction.Length() < Precision::Confusion()) direction = Base::Vector3f(0,1,0); float dia = pcConstraint->Diameter.getValue(); float radius = pcConstraint->Radius.getValue(); if (dia < 2 * radius) dia = 2 * radius; float angle = pcConstraint->ForceAngle.getValue() / 180 * M_PI; SbVec3f ax(axis.x, axis.y, axis.z); SbVec3f dir(direction.x, direction.y, direction.z); const SoSeparator* sep = static_cast<SoSeparator*>(pShapeSep->getChild(2)); updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia/2); updatePlacement(pShapeSep, 3, SbVec3f(dia/2 * sin(angle), 0, dia/2 * cos(angle)), SbRotation(ax, dir)); sep = static_cast<SoSeparator*>(pShapeSep->getChild(5)); updateArrow(sep, 0, dia/2, dia/8); } } else if ((strcmp(prop->getName(),"DirectionVector") == 0) || (strcmp(prop->getName(),"ForceAngle") == 0)) { // Note: "Reversed" also triggers "DirectionVector" if (pShapeSep->getNumChildren() > 0) { // Re-orient the symbol Base::Vector3f axis = pcConstraint->Axis.getValue(); Base::Vector3f direction = pcConstraint->DirectionVector.getValue(); if (direction.Length() < Precision::Confusion()) direction = Base::Vector3f(0,1,0); float dia = pcConstraint->Diameter.getValue(); float angle = pcConstraint->ForceAngle.getValue() / 180 * M_PI; SbVec3f ax(axis.x, axis.y, axis.z); SbVec3f dir(direction.x, direction.y, direction.z); /*Base::Console().Error("Axis: %f, %f, %f\n", axis.x, axis.y, axis.z); Base::Console().Error("Direction: %f, %f, %f\n", direction.x, direction.y, direction.z); SbRotation rot = SbRotation(ax, dir); SbMatrix m; rot.getValue(m); SbMat m2; m.getValue(m2); Base::Console().Error("Matrix: %f, %f, %f, %f\n", m[0][0], m[1][0], m[2][0], m[3][0]); // Note: In spite of the fact that the rotation matrix takes on 3 different values if 3 // normal directions are chosen, the resulting arrow will only point in two different // directions when ax = (1,0,0) (but for ax=(0,1,0) it points in 3 different directions!) */ updatePlacement(pShapeSep, 3, SbVec3f(dia/2 * sin(angle), 0, dia/2 * cos(angle)), SbRotation(ax, dir)); } } ViewProviderFemConstraint::updateData(prop); }
bool UniGridApprox::SurfMeshParam() { // hier wird das in MeshOffset erzeugte gitter parametrisiert // parametrisierung: (x,y) -> (u,v) , ( R x R ) -> ( [0,1] x [0,1] ) int n = m_Grid.size()-1; // anzahl der zu approximierenden punkte in x-richtung int m = m_Grid[0].size()-1; // anzahl der zu approximierenden punkte in y-richtung std::vector<double> dist_x, dist_y; double sum,d; Base::Vector3f vlen; m_uParam.clear(); m_vParam.clear(); m_uParam.resize(n+1); m_vParam.resize(m+1); m_uParam[n] = 1.0; m_vParam[m] = 1.0; // berechne knotenvektor in u-richtung (entspricht x-richtung) for (int j=0; j<m+1; ++j) { sum = 0.0; dist_x.clear(); for (int i=0; i<n; ++i) { vlen = (m_Grid[i+1][j] - m_Grid[i][j]); dist_x.push_back(vlen.Length()); sum += dist_x[i]; } d = 0.0; for (int i=0; i<n-1; ++i) { d += dist_x[i]; m_uParam[i+1] = m_uParam[i+1] + d/sum; } } for (int i=0; i<n; ++i) m_uParam[i] /= m+1; // berechne knotenvektor in v-richtung (entspricht y-richtung) for (int i=0; i<n+1; ++i) { sum = 0.0; dist_y.clear(); for (int j=0; j<m; ++j) { vlen = (m_Grid[i][j+1] - m_Grid[i][j]); dist_y.push_back(vlen.Length()); sum += dist_y[j]; } d = 0.0; for (int j=0; j<m-1; ++j) { d += dist_y[j]; m_vParam[j+1] = m_vParam[j+1] + d/sum; } } for (int j=0; j<m; ++j) m_vParam[j] /= n+1; /*cout << "uParam:" << endl; for(int i=0; i<m_uParam.size(); ++i){ cout << " " << m_uParam[i] << ", " << endl; } cout << "vParam:" << endl; for(int i=0; i<m_vParam.size(); ++i){ cout << " " << m_vParam[i] << ", " << endl; }*/ return true; }
void MeshAlgos::LoftOnCurve(MeshCore::MeshKernel &ResultMesh, const TopoDS_Shape &Shape, const std::vector<Base::Vector3f> &poly, const Base::Vector3f & up, float MaxSize) { TopExp_Explorer Ex; Standard_Real fBegin, fEnd; std::vector<MeshGeomFacet> cVAry; std::map<TopoDS_Vertex,std::vector<Base::Vector3f>,_VertexCompare> ConnectMap; for (Ex.Init(Shape, TopAbs_EDGE); Ex.More(); Ex.Next()) { // get the edge and the belonging Vertexes TopoDS_Edge Edge = (TopoDS_Edge&)Ex.Current(); TopoDS_Vertex V1, V2; TopExp::Vertices(Edge, V1, V2); bool bBegin = false,bEnd = false; // geting the geometric curve and the interval GeomLProp_CLProps prop(BRep_Tool::Curve(Edge,fBegin,fEnd),1,0.0000000001); int res = int((fEnd - fBegin)/MaxSize); // do at least 2 segments if(res < 2) res = 2; gp_Dir Tangent; std::vector<Base::Vector3f> prePoint(poly.size()); std::vector<Base::Vector3f> actPoint(poly.size()); // checking if there is already a end to conect if(ConnectMap.find(V1) != ConnectMap.end() ){ bBegin = true; prePoint = ConnectMap[V1]; } if(ConnectMap.find(V2) != ConnectMap.end() ) bEnd = true; for (long i = 0; i < res; i++) { // get point and tangent at the position, up is fix for the moment prop.SetParameter(fBegin + ((fEnd - fBegin) * float(i)) / float(res-1)); prop.Tangent(Tangent); Base::Vector3f Tng((float)Tangent.X(), (float)Tangent.Y(), (float)Tangent.Z()); Base::Vector3f Ptn((float)prop.Value().X(), (float)prop.Value().Y(), (float)prop.Value().Z()); Base::Vector3f Up (up); // normalize and calc the third vector of the plane coordinatesystem Tng.Normalize(); Up.Normalize(); Base::Vector3f Third(Tng%Up); // Base::Console().Log("Pos: %f %f %f \n",Ptn.x,Ptn.y,Ptn.z); unsigned int l=0; std::vector<Base::Vector3f>::const_iterator It; // got through the profile for(It=poly.begin();It!=poly.end();++It,l++) actPoint[l] = ((Third*It->x)+(Up*It->y)+(Tng*It->z)+Ptn); if(i == res-1 && !bEnd) // remeber the last row to conect to a otger edge with the same vertex ConnectMap[V2] = actPoint; if(i==1 && bBegin) // using the end of an other edge as start prePoint = ConnectMap[V1]; if(i==0 && !bBegin) // remember the first row for conection to a edge with the same vertex ConnectMap[V1] = actPoint; if(i ) // not the first row or somthing to conect to { for(l=0;l<actPoint.size();l++) { if(l) // not first point in row { if(i == res-1 && bEnd) // if last row and a end to conect actPoint = ConnectMap[V2]; Base::Vector3f p1 = prePoint[l-1], p2 = actPoint[l-1], p3 = prePoint[l], p4 = actPoint[l]; cVAry.push_back(MeshGeomFacet(p1,p2,p3)); cVAry.push_back(MeshGeomFacet(p3,p2,p4)); } } } prePoint = actPoint; } } ResultMesh.AddFacets(cVAry); }
void CurveProjectorWithToolMesh::makeToolMesh( const TopoDS_Edge& aEdge,std::vector<MeshGeomFacet> &cVAry ) { Standard_Real fBegin, fEnd; Handle(Geom_Curve) hCurve = BRep_Tool::Curve(aEdge,fBegin,fEnd); float fLen = float(fEnd - fBegin); Base::Vector3f cResultPoint; unsigned long ulNbOfPoints = 15,PointCount=0/*,uCurFacetIdx*/; std::vector<LineSeg> LineSegs; MeshFacetIterator It(_Mesh); Base::SequencerLauncher seq("Building up tool mesh...", ulNbOfPoints+1); std::map<unsigned long,std::vector<Base::Vector3f> > FaceProjctMap; for (unsigned long i = 0; i < ulNbOfPoints; i++) { seq.next(); gp_Pnt gpPt = hCurve->Value(fBegin + (fLen * float(i)) / float(ulNbOfPoints-1)); Base::Vector3f LinePoint((float)gpPt.X(), (float)gpPt.Y(), (float)gpPt.Z()); Base::Vector3f ResultNormal; // go through the whole Mesh for(It.Init();It.More();It.Next()) { // try to project (with angle) to the face if (It->IntersectWithLine (Base::Vector3f((float)gpPt.X(),(float)gpPt.Y(),(float)gpPt.Z()), It->GetNormal(), cResultPoint) ) { if(Base::Distance(LinePoint,cResultPoint) < 0.5) ResultNormal += It->GetNormal(); } } LineSeg s; s.p = Base::Vector3f((float)gpPt.X(), (float)gpPt.Y(), (float)gpPt.Z()); s.n = ResultNormal.Normalize(); LineSegs.push_back(s); } Base::Console().Log("Projection map [%d facets with %d points]\n",FaceProjctMap.size(),PointCount); // build up the new mesh Base::Vector3f lp(FLOAT_MAX,0,0), ln, p1, p2, p3, p4,p5,p6; float ToolSize = 0.2f; for (std::vector<LineSeg>::iterator It2=LineSegs.begin(); It2!=LineSegs.end();++It2) { if(lp.x != FLOAT_MAX) { p1 = lp + (ln * (-ToolSize)); p2 = lp + (ln * ToolSize); p3 = lp; p4 = (*It2).p; p5 = (*It2).p + ((*It2).n * (-ToolSize)); p6 = (*It2).p + ((*It2).n * ToolSize); cVAry.push_back(MeshGeomFacet(p3,p2,p6)); cVAry.push_back(MeshGeomFacet(p3,p6,p4)); cVAry.push_back(MeshGeomFacet(p1,p3,p4)); cVAry.push_back(MeshGeomFacet(p1,p4,p5)); } lp = (*It2).p; ln = (*It2).n; } }