Open KevinHuyskens opened 6 years ago
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);
}
}'
Hi @Kevinator123 so you want to get all surfaces as one list, correct? So my take would be:
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
Did you check for nested instances etc?
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.
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?
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....
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.
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: (Don't take into account the textures and colors, haven't spend time on that yet because it's not the main priority)
@ KevinHuyskens Hello, do you import SKP with unity?I am doing the same thing, can you give me some reference?
@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.
@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)
@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 :')
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.
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 ;)
Let me know if anything is missing in the library
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.