Exemple #1
0
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;
        }
    }
}
Exemple #2
0
/*! \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;
}
Exemple #3
0
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;
}
Exemple #5
0
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;
  }



}