Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to handle Surfaces part of a component but not an instance? #18

Open
KevinHuyskens opened this issue Aug 30, 2018 · 16 comments
Open
Assignees
Labels

Comments

@KevinHuyskens
Copy link

Each vertice that is part of a surface which is part of an instance you can use .GetTransformed on and you get the correct position of the vertice to build your mesh but some components aren't part of an instance and contain surfaces that aren't part of an instance so how do you go about positioning those vertices in the correct place?

Sorry I have to ask it here but I don't know where else to go, the documentation on SketchUp file structures is very limited.

@KevinHuyskens
Copy link
Author

KevinHuyskens commented Aug 31, 2018

Perhaps an other way to put it, do you know of a way to get all the faces with the correct transform? Because at the moment some faces don't get transforms applied. Here is my class:

' class SketchUpReader
{
private Vector3 vertice = new Vector3();
private Vector3[] face = new Vector3[3];
UdpClient client = new UdpClient();

    List<string> faceStrings = new List<string>();

    public int verticeCount = 0;

    public void loadSkp(string path)
    {
        var currentTime = DateTime.Now;
        SketchUp skp = new SketchUp();
        if (skp.LoadModel(path, true))
        { 
            foreach(Group g in skp.Groups)
            {
                foreach(Instance i in g.Instances)
                {
                    Component comp = i.Parent as Component;

                    foreach(Surface s in g.Surfaces)
                    {
                        GetGroupInstanceSurfaceVertices(s, g, i);
                    }
                }
                foreach(Surface s in g.Surfaces)
                {
                    GetGroupSurfaceVertices(s, g);
                }
            }
            if (skp.Surfaces.Count == 0)
            {
                foreach (Instance i in skp.Instances)
                {
                    faceStrings.Add(new Vector3(1, 1, 1).ToTransformString());
                    faceStrings.Add(new Vector3(1, 1, 1).ToTransformString());
                    Component comp = i.Parent as Component;

                    foreach (Surface s in comp.Surfaces)
                    {
                        GetInstanceSurfaceVertices(s, i);
                    }

                    foreach (KeyValuePair<string, SketchUpNET.Component> c in skp.Components)
                    {
                        foreach (Instance instance in c.Value.Instances)
                        {
                            faceStrings.Add(new Vector3(1, 1, 1).ToTransformString());
                            faceStrings.Add(new Vector3(1, 1, 1).ToTransformString());

                            Component compo = instance.Parent as Component;

                            foreach (Surface s in compo.Surfaces)
                            {
                                GetNestedInstanceSurfaceVertices(s, i, instance);
                            }
                        }
                    }
                }
                new Thread(() =>
                {
                    Thread.CurrentThread.IsBackground = true;
                    client.SendData(faceStrings);
                }).Start();
            }
            else
            {
                foreach (Surface s in skp.Surfaces)
                {
                    GetSurfaceVertices(s, faceStrings);
                }
                new Thread(() =>
                {
                    Thread.CurrentThread.IsBackground = true;
                    client.SendData(faceStrings);
                }).Start();
            }

            File.WriteAllLines(@"c:\Users\Kevin\Desktop\testfile.txt", faceStrings);

            new Thread(() =>
            {
                Thread.CurrentThread.IsBackground = true;
                Thread.Sleep(5000);
                client.SendData(new List<string> { "done" });
            }).Start();
        }
    }

    public void GetSurfaceVertices(Surface surface, List<string> stringList)
    {

        Mesh m = surface.FaceMesh;

        foreach(MeshFace mf in m.Faces)
        {
            verticeCount += 3;

            SetVertex(vertice, m.Vertices[mf.A]);
            face[0] = vertice;
            stringList.Add(vertice.ToString());

            SetVertex(vertice, m.Vertices[mf.B]);
            face[1] = vertice;
            stringList.Add(vertice.ToString());

            SetVertex(vertice, m.Vertices[mf.C]);
            face[2] = vertice;
            stringList.Add(vertice.ToString());
        }
    }

    public void GetInstanceSurfaceVertices(Surface surface, Instance i)
    {
        Mesh m = surface.FaceMesh;

        foreach (MeshFace mf in m.Faces)
        {
            verticeCount += 3;

            SetVertex(vertice, i.Transformation.GetTransformed(m.Vertices[mf.A]));
            face[0] = vertice;
            faceStrings.Add(vertice.ToString());

            SetVertex(vertice, i.Transformation.GetTransformed(m.Vertices[mf.B]));
            face[1] = vertice;
            faceStrings.Add(vertice.ToString());

            SetVertex(vertice, i.Transformation.GetTransformed(m.Vertices[mf.C]));
            face[2] = vertice;
            faceStrings.Add(vertice.ToString());
        }
    }

    public void GetGroupSurfaceVertices(Surface surface, Group g)
    {
        Mesh m = surface.FaceMesh;

        foreach (MeshFace mf in m.Faces)
        {
            verticeCount += 3;

            SetVertex(vertice, g.Transformation.GetTransformed(m.Vertices[mf.A]));
            face[0] = vertice;
            faceStrings.Add(vertice.ToString());

            SetVertex(vertice, g.Transformation.GetTransformed(m.Vertices[mf.B]));
            face[1] = vertice;
            faceStrings.Add(vertice.ToString());

            SetVertex(vertice, g.Transformation.GetTransformed(m.Vertices[mf.C]));
            face[2] = vertice;
            faceStrings.Add(vertice.ToString());
        }
    }

    public void GetGroupInstanceSurfaceVertices(Surface surface, Group g, Instance i)
    {
        Mesh m = surface.FaceMesh;

        foreach (MeshFace mf in m.Faces)
        {
            verticeCount += 3;

            SetVertex(vertice, g.Transformation.GetTransformed(i.Transformation.GetTransformed(m.Vertices[mf.A])));
            face[0] = vertice;
            faceStrings.Add(vertice.ToString());

            SetVertex(vertice, g.Transformation.GetTransformed(i.Transformation.GetTransformed(m.Vertices[mf.B])));
            face[1] = vertice;
            faceStrings.Add(vertice.ToString());

            SetVertex(vertice, g.Transformation.GetTransformed(i.Transformation.GetTransformed(m.Vertices[mf.C])));
            face[2] = vertice;
            faceStrings.Add(vertice.ToString());
        }
    }

    public void GetNestedInstanceSurfaceVertices(Surface surface, Instance rootInstance,Instance nestedInstance)
    {
        Mesh m = surface.FaceMesh;

        foreach (MeshFace mf in m.Faces)
        {
            verticeCount += 3;

            SetVertex(vertice, rootInstance.Transformation.GetTransformed(nestedInstance.Transformation.GetTransformed(m.Vertices[mf.A])));
            face[0] = vertice;
            faceStrings.Add(vertice.ToString());

            SetVertex(vertice, rootInstance.Transformation.GetTransformed(nestedInstance.Transformation.GetTransformed(m.Vertices[mf.B])));
            face[1] = vertice;
            faceStrings.Add(vertice.ToString());

            SetVertex(vertice, rootInstance.Transformation.GetTransformed(nestedInstance.Transformation.GetTransformed(m.Vertices[mf.C])));
            face[2] = vertice;
            faceStrings.Add(vertice.ToString());
        }
    }

    private void SetVertex(Vector3 vertex, Vertex skpVertex)
    {
        vertex.x = skpVertex.X;
        vertex.y = skpVertex.Y;
        vertex.z = skpVertex.Z;
    }

    public static bool ReformatModel(string filepath, string version, string newfilepath)
    {
        SketchUp skp = new SketchUp();
        SKPVersion v = SKPVersion.V2017;
        switch (version)
        {
            case "2014": v = SKPVersion.V2014; break;
            case "2015": v = SKPVersion.V2015; break;
            case "2016": v = SKPVersion.V2016; break;
            case "2017": v = SKPVersion.V2017; break;
            case "2018": v = SKPVersion.V2018; break;
        }
        return skp.SaveAs(filepath, v, newfilepath);
    }
}'

@moethu
Copy link
Owner

moethu commented Sep 6, 2018

Hi @Kevinator123 so you want to get all surfaces as one list, correct?
So my take would be:

  1. get all surfaces into a list
  2. walk through all instances and get the surfaces and add them to the list
    like this one:
    https://github.com/moethu/SketchUpNET/blob/master/SketchUp/SketchUpNET/SketchUpForDynamo/SketchUp.cs#L280-L308

@moethu moethu self-assigned this Sep 6, 2018
@moethu moethu added the question label Sep 6, 2018
@KevinHuyskens
Copy link
Author

Thanks for answering, the way I do it right now is check each instance, surface and group on model level and keep on going down the nested components but I'm still missing faces somehow.

https://github.com/Kevinator123/SketchUpReader/blob/master/ReadSKPConsole/Program.cs

@moethu
Copy link
Owner

moethu commented Sep 7, 2018

Did you check for nested instances etc?

@KevinHuyskens
Copy link
Author

I think I checked all nested surfaces, foreach instance I get the parent component, for each of those components I draw the surfaces, I check the groups and check the instances. For each group I check the instances and their parent components and nested groups and for components I draw the surfaces, check for new instances and new groups. I also check for surfaces, groups and components on model level.

@moethu
Copy link
Owner

moethu commented Sep 9, 2018

Are you able to check your SKP file to see which geometries haven't been imported?
Where are they located? within a component or at root level simply in the model?
What kind of geometry is it? Maybe it cannot be meshed?

@KevinHuyskens
Copy link
Author

KevinHuyskens commented Sep 10, 2018

It definitely are just faces so I think it can be meshed, they are part of an instance. But what I just noticed is that everything that doesn't draw has as type: Type undefined. Perhaps that has something to do with it?

Then again some things that have type undefined do draw....

@moethu
Copy link
Owner

moethu commented Sep 11, 2018

Type undefined sounds odd, can you share your skp model with me so I can have a look. And please point me to the failing faces.

@KevinHuyskens
Copy link
Author

So here is a skp file that has a lot of missing faces: https://drive.google.com/open?id=1Qrv8ca_dGlpYQqXdsAImo9u-jls35JND

So that's how it's supposed to look and this is how it looks:
image
(Don't take into account the textures and colors, haven't spend time on that yet because it's not the main priority)

@13704017891
Copy link

@ KevinHuyskens Hello, do you import SKP with unity?I am doing the same thing, can you give me some reference?

@moethu
Copy link
Owner

moethu commented Jul 18, 2019

@KevinHuyskens , sorry just realizing you answered quite some time ago. I was wondering when I looked at your code: what about instances that contain other instances? and what about components containing components? both cases are not coughed.

@KevinBME
Copy link

KevinBME commented Aug 9, 2019

@13704017891 Yes, I load the file externally and pass all the faces through with a named pipe. (haven't worked on this project for quiete some time).
@moethu I'll try this when I have time, see if it works, I'll keep you posted once I get to it.

(Same person, different account)

@KevinHuyskens
Copy link
Author

@moethu took a look at your suggestion just now, but your library's Instance object doesn't contain any Instances and Component doesn't contain any Components so I can't catch those cases :')

@moethu
Copy link
Owner

moethu commented Aug 22, 2019

Did you check the Dynamo implementation as a reference? The components in there were able to catch all geometries so far. https://github.com/moethu/SketchUpNET/blob/master/SketchUp/SketchUpNET/SketchUpForDynamo/SketchUp.cs
Maybe I was missing something, I will setup a Windows VM to test you implementation but please have a look if you got all the nested elements etc.

@KevinHuyskens
Copy link
Author

So instead of going over my old code I started completely over, here is a code sample for writing out everything in a treeview in wpf (I excluded edges and curves because I don't need them).

Here is the sample: https://pastebin.com/XpRWYruK
(start a new wpf project and add a treeview with name "treeView" if you want to use it yourself and change the model path and perhaps the namespace.)

Redoing it I can already see I missed some essential parts in my previous approach so I'll let you know how it goes from here on, but I've a feeling that I'm on the right track ;)

@moethu
Copy link
Owner

moethu commented Aug 26, 2019

Let me know if anything is missing in the library

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants