Continue to Site

Eng-Tips is the largest engineering community on the Internet

Intelligent Work Forums for Engineering Professionals

  • Congratulations The Obturator on being selected by the Eng-Tips community for having the most helpful posts in the forums last week. Way to Go!

NX8: How to convert Planar, Spherical, Conical etc. to B-surfaces ? 3

Status
Not open for further replies.

Dottore93

Automotive
Oct 22, 2013
3
Hi @all,

Being quite a novice in UG/NX programming, I need to program an external application that reads in a .PRT file, traverses through the entities, converts all Faces to (trimmed) B-surfaces (Nurbs) and passes these to another format. Part of the code is a routine processFace as follows:

Code:
void processFace(NXOpen::Face* face, ...) {

   // (...) misc initializations and checks
  
   tag_t facetag = face->Tag();
   UF_MODL_bsurface_s bsurf;
   bool ok = (UF_MODL_ask_bsurf(facetag, &bsurf) == 0);
   if (ok) { // filled bsurf successfully
      processNurbsSurface(bsurf); 
   }
   else { // no success, need to convert surface individually by its type
      NXOpen::Face::FaceType type = face->SolidFaceType();
      if (type == NXOpen::Face::FaceType::FaceTypePlanar) {
         // get plane data from Face and build nurbs
      }
      else if (type == NXOpen::Face::FaceType::FaceTypeCylindrical ) {
         // get cylinder data from Face and build nurbs
      }
      // and so on for all other possible basic surface types ...
      ...
      else return;
   }

   // (...) now process the loops, get attributes etc.

   UF_MODL_free_bsurf_data(&bsurf);
}

Since I haven't programmed yet all the basic surface conversions Plane->Nurbs, Cylinder->Nurbs etc., I would be happy to have a general conversion routine in UG/NX that would take a NXOpen::Face as input and create me a Nurbs surface from it, if possible without loss of geometric information (and for most of the basic surface types that IS mathematically possible).

Is there such a conversion routine in UG/NX? I have browsed the docs and this forum for several hours, but could not find any helpful hint. Sorry if this is a FAQ. Any help is appreciated!
 
Replies continue below

Recommended for you

There is no interactive,as far as i can remember, way to convert faces to b-surfaces.
The way I used to do it was to extract a copy of the face-s in B-surface representation.
( Later versions of NX will in a number of features, such as X-Form etc, do a conversion on the fly when one are about to modify/deform the face-s.)
- search for the extract geometry feature, it should have the option you need.

See attached image.

Regards,
Tomas



 
 http://files.engineering.com/getfile.aspx?folder=4511bcda-1337-4e41-b725-db582800dbac&file=extract_geometry.png
Interactive you can do it using
Insert->Associative Copy->Extract Geometry

Programming you can use ExtractFaceBuilder Class

Frank Swinkels
 
Optimize face will not convert a simple type face such as a planar face into a more complex B-surface, - The planar is better/ simpler/ faster in all aspects except it is always planar.- It cannot change the shape from planar to ...

I assume that Dottore93 wants to convert everything into B-surfaces because of some logical reason, a guess would be some form of export to a different system which only accepts B-surfaces.

Regards,
Tomas
 
Toost said:
I assume that Dottore93 wants to convert everything into B-surfaces because of some logical reason, a guess would be some form of export to a different system which only accepts B-surfaces.

Yes, that's exactly the reason.

FrankSwinks said:
Programming you can use ExtractFaceBuilder Class

I picked up Franks proposal and tried the following:

Code:
bool processPart(NXOpen::Part* part) {

  // create a ExtractFaceBuilder instance...
  NXOpen::Features::Feature* nullFeatures_Feature(NULL);
  NXOpen::Features::FeatureCollection* features = part->Features();
  NXOpen::Features::ExtractFaceBuilder* efb = features->CreateExtractFaceBuilder(nullFeatures_Feature);

  // ... and set some properties which sound reasonable
  efb->SetType(NXOpen::Features::ExtractFaceBuilder::ExtractTypeBody);
  efb->SetSurfaceType(NXOpen::Features::ExtractFaceBuilder::FaceSurfaceTypeGeneralBSurface);
  efb->SetFaceOption(NXOpen::Features::ExtractFaceBuilder::FaceOptionTypeAllBodyFaces);

  // traverse through the part's bodies
  NXOpen::BodyCollection* bodyList = part->Bodies();
  NXOpen::BodyCollection::iterator itr;
  for (itr = bodyList->begin(); itr != bodyList->end(); ++itr) {
     NXOpen::Body* body = *itr;
     bool addok = efb->BodyToExtract()->Add(body); // Add body to ExtractFaceBuilder
     bool ok = efb->Validate(); // efb ready to go?

     if (ok) { // Go! But what to do with the resulting object?
       NXOpen::NXObject* obj = efb->Commit();
       NXOpen::Body* nobody = dynamic_cast<NXOpen::Body*>(obj); // Fails!!! nobody=0
     }

     // traverse through the body's faces
     std::vector<NXOpen::Face*>& faces = body->GetFaces();
     size_t nFaces = faces.size(), i;
     for (i=0; i<nFaces; i++) {
        NXOpen::Face* face = faces[i];  
        processFace(face);
     }
  }
}

Now I'm stuck since I don't know how to use the NXObject* that Commit() returns. dynamic_cast to Body* (hoping to get the new body with the resulting B-Surfaces in it) fails. Any ideas?
 
Instead of passing a body into ExtractFaceBuilder you need to get the faces from the body and pass them into ExtractFaceBuilder.

Frank Swinkels
 
Thanks to Frank (and all the other contributors). I found a solution that works for me:

Code:
void processFace(NXOpen::Face* face) {

   if (!face) return;

   // face is already of parametric type? not much to do.
   NXOpen::Face::FaceType type = face->SolidFaceType();
   if (type == NXOpen::Face::FaceTypeParametric) {
      processParametricFace(face);
      return;
   }

   // otherwise instantiate and set the nurbs conversion tool...
   NXOpen::Features::Feature* nullFeatures_Feature(NULL);
   NXOpen::Features::FeatureCollection* features = m_part->Features();
   NXOpen::Features::ExtractFaceBuilder* efb = features->CreateExtractFaceBuilder(nullFeatures_Feature);
   if (!efb) return;
   efb->SetType(NXOpen::Features::ExtractFaceBuilder::ExtractTypeFace);
   efb->SetSurfaceType(NXOpen::Features::ExtractFaceBuilder::FaceSurfaceTypeGeneralBSurface);
   efb->SetFaceOption(NXOpen::Features::ExtractFaceBuilder::FaceOptionTypeSingleFace);

   // ... and perform the conversion.
   try {
      efb->FacesToExtract()->Add(face);
      if (efb->Validate()) {
         NXOpen::NXObject* obj = efb->Commit();
         NXOpen::Features::BodyFeature* fe = dynamic_cast<NXOpen::Features::BodyFeature*>(obj);
         if (fe) {
            std::vector<NXOpen::Face*>& nurbsfaces = fe->GetFaces();
            size_t nNurbsFaces = nurbsfaces.size(), j;
            for (j=0; j<nNurbsFaces; j++) {
               NXOpen::Face* nface = nurbsfaces[j];  
               processParametricFace(nface);
            }
         }
      }
   }
   catch (const NXOpen::NXException& ex) {
      std::cerr << "Caught exception " << ex.Message() << std::endl;
   }

   efb->Destroy();
}
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor