Diff between Brep.Surfaces and Brep.Faces.UnderlyingSurface()

Hi There,

I am trying to set the domains of a generated surface and then test if a point is at an Interior relationship to it.

The logic goes something like this.

  1. Create Brep from Patch of Curves (this sometimes automatically sets the domains to something I don’t find intuitive since I then use the domains to find points on the surface)
  2. Take Brep and get FaceList, and for each face get the underlying surface.
  3. Try finding some points that are interior to the trimmed face.
  4. If can’t find any, change the domains of the surface based on how many points I want to find and look again.

I’ve found when I call the BrepFaceList.UnderlyingSurface().SetDomain(X, _____) it is not changing it, however when I use the SetDomain of a Surface from the BrepSurfaceList it does work and does change the domain.

Are the Underlying Surfaces in BrepFaceList related to the surfaces in BrepSurfaceList ??
If not, what’s the best way to utilize a domain change on teh BrepSurfaceList but then test if a point at (u,v) is interior to the trimmed face?

Thanks!

-Chris Slaughter

They are one in the same.

Dale,

When I set the domains with BrepFace[X].UnderlyingSurface().SetDomain(0,___) and then get the domains from the SurfaceList[X].Domain(0), they are not the same, furthermore if I re-get the BrepFace.UnderlyingSurface().Domain(0) after setting it, it has not changed.

Here is a code snippet and it’s resulting output inside of Rhino.

Code

        RhinoApp.WriteLine("Domain of facelist[0] u:{0}, v:{1}", hereFaceList[0].UnderlyingSurface().Domain(0), hereFaceList[0].UnderlyingSurface().Domain(1));
        RhinoApp.WriteLine("Surfacelist[0] u:{0}, v:{1}", hereSurfList[0].Domain(0), hereSurfList[0].Domain(1));
        newBrep.Surfaces[0].SetDomain(0, tempInterval);
        newBrep.Surfaces[0].SetDomain(1, tempInterval);
        hereFaceList[0].UnderlyingSurface().SetDomain(0, tempInterval);
        hereFaceList[0].UnderlyingSurface().SetDomain(1, tempInterval);
        RhinoApp.WriteLine("Domain of facelist[0] u:{0}, v:{1}", hereFaceList[0].UnderlyingSurface().Domain(0), hereFaceList[0].UnderlyingSurface().Domain(1));
        RhinoApp.WriteLine("Surfacelist[0] u:{0}, v:{1}", hereSurfList[0].Domain(0), hereSurfList[0].Domain(1));

        if (hereSurfList[0].Equals(hereFaceList[0].UnderlyingSurface()))
        {
            RhinoApp.WriteLine("THIS THING IS EQUAL");
        }
        else
            RhinoApp.WriteLine("THIS THING IS NOT EQUAL");

Rhino Output

Domain of facelist[0] u:0,1, v:0,1
Surfacelist[0] u:0,1, v:0,1
Domain of facelist[0] u:0,1, v:0,1
Surfacelist[0] u:0,15, v:0,15
THIS THING IS NOT EQUAL

Any help here is greatly appreciated.

Dale,

I realized that there was a difference between me using a reference to the BREP in the newBrep.Surfaces[X].SetDomain method but I was utilizing the FaceList[X].UnderlyingSurface().SetDomain method, so I was curious if the Lists were a safe copy or something so I swapped them,

Code

        RhinoApp.WriteLine("Domain of facelist[0] u:{0}, v:{1}", hereFaceList[0].UnderlyingSurface().Domain(0), hereFaceList[0].UnderlyingSurface().Domain(1));
        RhinoApp.WriteLine("Surfacelist[0] u:{0}, v:{1}", hereSurfList[0].Domain(0), hereSurfList[0].Domain(1));
        hereSurfList[0].SetDomain(0, tempInterval);
        hereSurfList[0].SetDomain(1, tempInterval);
        //newBrep.Surfaces[0].SetDomain(0, tempInterval);
        //newBrep.Surfaces[0].SetDomain(1, tempInterval);
        newBrep.Faces[0].SetDomain(0, tempInterval);
        newBrep.Faces[0].SetDomain(1, tempInterval);
        //hereFaceList[0].UnderlyingSurface().SetDomain(0, tempInterval);
        //hereFaceList[0].UnderlyingSurface().SetDomain(1, tempInterval);
        RhinoApp.WriteLine("Domain of facelist[0] u:{0}, v:{1}", hereFaceList[0].UnderlyingSurface().Domain(0), hereFaceList[0].UnderlyingSurface().Domain(1));
        RhinoApp.WriteLine("Surfacelist[0] u:{0}, v:{1}", hereSurfList[0].Domain(0), hereSurfList[0].Domain(1));

Result

Domain of facelist[0] u:0,1, v:0,1
Surfacelist[0] u:0,1, v:0,1
Domain of facelist[0] u:0,15, v:0,15
Surfacelist[0] u:0,15, v:0,15
THIS THING IS NOT EQUAL

Apposed to my post I just did above where the domain of the facelist[x].UnderlyingSurface().SetDomain, with this code reference the Brep.Faces[X] it now properly sets the domain, However I used the SurfList[X].SetDomain function instead of the BrepSurfaceList[X].SetDomain and it also works. I’m not sure if this is intentional, it doesn’t make a lot of sense to me.

Chris,
I suspect you are not comparing corresponding geometry.

The order of faces is not the same as the order of surfaces in the brep faces/surfaces arrays.
You can get the corresponding underlying surface index using:
facelist[0].SurfaceIndex

Thanks Rajaa,

In a larger surface with multiple trims or polysurface I could see this being an issue, prior to this code I have tested this specific example (just to know things could work in a simple case) and both the BrepFaceList.Count and BrepSurfaceList.Count are 1, the test case is on a singular open surface. I did just verify the surface index as you suggested and it is at list index 0

That is funny. I’ll test at my end. The two should be the same unless we are passing a “copy” of the underlying surface and hence not updating the domain of the actual surface. I’ll get back to you shortly.

Ok, I see it. @stevebaer can probably tell what is going on here.

This is the code I used. Notice that if you set the Face[0].Domain, then the change is correct and is reflected for both the surface[0] and the face[0].UnderlyingSurface() working as expected. But it does not appear to work properly if setting the domain of surface[0] directly.

    protected override Result RunCommand(RhinoDoc doc, RunMode mode)
    {
        // Select single face brep
        Rhino.Input.Custom.GetObject go = new Rhino.Input.Custom.GetObject();
        go.SetCommandPrompt("Select a single face brep to test domain");
        go.GeometryFilter = Rhino.DocObjects.ObjectType.Brep;
        go.SubObjectSelect = false;
        go.Get();
        if (go.CommandResult() != Rhino.Commands.Result.Success)
            return go.CommandResult();

        Rhino.Geometry.Brep brep = go.Object(0).Brep();
        if (null == brep)
            return Result.Failure;

        //Test before setting to new domain
        RhinoApp.WriteLine("Brefore: Domain of brep.Faces[0].UnderlyingSurface u:{0}, v:{1}", brep.Faces[0].UnderlyingSurface().Domain(0), brep.Faces[0].UnderlyingSurface().Domain(1));
        RhinoApp.WriteLine("Brefore: Domain of brep.Surfaces[0] u:{0}, v:{1}", brep.Surfaces[0].Domain(0), brep.Surfaces[0].Domain(1));

        //Set new interval
        Interval tempInterval = new Interval(0, 10);

        //This gives unexpected result setting surface domain only, but not the face or face.underlyingsurface domain
        brep.Surfaces[0].SetDomain(0, tempInterval);
        brep.Surfaces[0].SetDomain(1, tempInterval);

        //This gives the correct result (setting both face, face.underlyingsurface and surface domain to the new interval)
        //brep.Faces[0].SetDomain(0, tempInterval);
        //brep.Faces[0].SetDomain(1, tempInterval);

        //Test after setting to new domain
        RhinoApp.WriteLine("After: Domain of brep.Faces[0].UnderlyingSurface u:{0}, v:{1}", brep.Faces[0].UnderlyingSurface().Domain(0), brep.Faces[0].UnderlyingSurface().Domain(1));
        RhinoApp.WriteLine("After: Domain of brep.Surfaces[0] u:{0}, v:{1}", brep.Surfaces[0].Domain(0), brep.Surfaces[0].Domain(1));

        return Result.Success;
    }

Thanks Rajaa,

I appreciate the time to test it. I’ll utilize the brep.Faces[0] list, but just so you know I also had unexpected results with a variable as the list. For instance

faceList = Brep.Faces;
Faces[0].UnderlyingSurface().SetDomain(X,interval); – Did not work

Brep.Faces[0].UnderlyingSurface().SetDomain(X, interval) – also did not work

Both Brep.Surfaces[0].SetDomain(X,interval) and SurfaceFaceList[0].SetDomain(X,interval) – worked only for the surface list, not for the face list.

Don’t know if that is useful for you guys. Thanks again for your help!

faceList = Brep.Faces;
Faces[0].UnderlyingSurface().SetDomain(X,interval); – Did not work
Brep.Faces[0].UnderlyingSurface().SetDomain(X, interval) – also did not work

Both lines are the same, and the result is expected in this case. I think this is because “Brep.Faces[0].UnderlyingSurface()” returns a copy of the surface and hence changing its domain does not affect the original surface.

Brep.Surfaces[0].SetDomain(X,interval)

Yes, this is the one that is not working as expected.

brep.Faces[0].SetDomain(X,Interval):

Works here for both surfaces and faces.