Flip Surface Normal C++

Hi,

I have seen some discussions about fliping the normal of a surface in RhinoCommon but I am not finding parallel methods in C++ SDK. I understand that the BrepFace and the underlying surface can have different orientations… So, my question is, if I have a “simple” Brep, a single trimmed surface (one brep face), like in the image bellow…what is the proper way to flip the normal so that it points in the opposite direction and that BrepFace and underlying surface have the same orientation?

I ask this because when I use some plug-ins I run into some weird errors when I simply manually use Dir->Flip on the surface, and my guess is that comes from the disparity between the orientation of the BrepFace and the underlying surface. I realized that the result that NormalAt() method gives me (that ON_BrepFace inherits from ON_Surface) does not coincide with the Dir - I guess this is the part of the same problem…so a small clarification would be appreciated.

tempsrf

Thanks

Hi @dimcic,

Here is the proper way of calculating the normal direction of a Brep face.

Does this help?

– Dale

Hi Dale,

thanks. I understand that the Brep Face and the underlying surface can have different orientation…but I do not get two things:

  1. If I “catch them” being not aligned, what can I do to align them? Can I switch one of the directions in the code somehow? Of the Face or of the underlying surface?

  2. “Catching” them is not so easy as I thought…for example look at this image. The line represents the normal ( panelnormal = srfbrep->m_F[0].NormalAt(u,v); ), and the Dir command shows in the opposite direction…but nevertheless srfbrep->m_F[0].m_bRev is false…so that is what confuses me…shoudn`t m_bRev be true in that case? So for a set of surfaces I get m_bRev false for all of them, but for many of them (not all) the normal line and the Dir line are pointing in the opposite directions…

I am having some problems with importing surfaces to Revit…the import very often results in bad surfaces…and although this might not be the reason why some surfaces have errors in Revit, it could be…and even if it is not, I am interested in understanding this…

Thanks!

Hi @dimcic,

Read the comments for ON_Brep::FlipReversedSurfaces. I think this is what you are looking for.

– Dale

Thanks Dale,

this does make the normal and the dir to point in the same direction. I have a very short Yes/No question that is connected to my first question, but could be understood more general:

If I want to change the attribute of a Brep that is in the Document - not copy the brep and create a new one, but actually flip the normal of the CRhinoObject i selected…is the proper way to do it to simply cast the CRhinoObject to CRhinoBrepObject, use its Brep() function to point to the underlying Brep and call FlipReversedSurfaces?

Hi @dimcic,

This is the proper way:

CRhinoCommand::result CCommandTest::RunCommand(const CRhinoCommandContext& context)
{
  CRhinoGetObject go;
  go.SetCommandPrompt(L"Select surfaces and polysurfaces to flip reversed surfaces");
  go.SetGeometryFilter(CRhinoGetObject::surface_object|CRhinoGetObject::polysrf_object);
  go.EnableSubObjectSelect(FALSE);
  go.EnableGroupSelect();
  go.GetObjects(1, 0);
  if (go.CommandResult() != CRhinoCommand::success)
    return go.CommandResult();

  const int object_count = go.ObjectCount();
  for (int i = 0; i < object_count; i++)
  {
    const CRhinoObjRef& obj_ref = go.Object(i);
    const ON_Brep* brep = obj_ref.Brep();
    if (0 == brep)
      continue;

    bool bRev = false;
    for (int fi = 0; fi < brep->m_F.Count(); fi++)
    {
      if (brep->m_F[fi].m_bRev)
      {
        bRev = true;
        break;
      }
    }

    if (bRev)
    {
      ON_Brep new_brep(*brep);
      new_brep.FlipReversedSurfaces();
      context.m_doc.ReplaceObject(obj_ref, new_brep);
    }
  }

  return CRhinoCommand::success;
}

– Dale