Crazy face problem


#1

We write SKP files from our CAD program. We recently started to see a problem with the files in Sketchup. The attached file is a simple box. Some of our customers (only some) and my machine will read this in as 6 separate faces. On other computers this is a normal box that can be edited. It is important that this read in as a box without manipulation.

What possibly could be happening? Are we creating a bad SKP file?

boxtest.skp (6.9 KB)


#2

You have somehow put the Faces on the default layer and the Edges on Layer0. This is causing the peculiar results you see.


#3

Also, there are two sets of edges for the one set of faces. I’m not sure how this came to be.

Shep


#4

I would guess the two sets of edges are a artifact of the first problem. We will take a closer look at the face/edge layers and see if that clears it up. Thank you.


#5

Hi Shep,

In a nutshell this is how I add our meshes to the SketchUp model

For each mesh:

  1. I add all of the vertexes from our mesh to a SUGeometryInputRef with the function SUGeometryInputAddVertex.

For each face in the mesh:
2) I make a loop with SULoopInputCreate.

  1. I add vertex indexes from step 1 to the loop with SULoopInputAddVertexIndex

  2. I set SULoopInputEdgeSetSoft and SULoopInputEdgeSetSmooth to true if the faces that share the edge in our mesh have the same vertex index, ie share a vertex rather that having their own, like you would see at the corner of a box.

  3. I use SUGeometryInputAddFace to make a face with the loop.

  4. If there happen to be inner loops I use SUGeometryInputFaceAddInnerLoop to add them.

  5. I use SUGeometryInputFaceSetLayer to set the layer of the face.

  6. I use SUGeometryInputFaceSetFrontMaterial to set the material of the face.

For all meshes in the model:
9) Once steps 2 though 8 have been repeated for all faces in the mesh (1 will be repeated too if there is more than 1 mesh in the model), I use SUEntitiesFill to add the SUGeometryInputRef to the root SUEntitiesRef.

The only place I ever set a layer is on the face. I never add edges so to speak, only vertexes to loops.

I should mention that this is what we’re doing with the Trimble SDK. I imagine it’s something similar with the Google SDK but I haven’t looked at that recently.

Tim


#6

OK. I was hoping you guys might look at this and be able to recognize where I might be missing something. Let me take a different approach by asking a few questions.

Is there any way to set texture coordinates on a face besides using a SUMaterialInput as an argument passed to SUGeometryInputFaceSetFrontMaterial or SUGeometryInputFaceSetBackMaterial?

I’m using SUGeometryInputFaceSetLayer to set the layer of the face (I only have an index, not an SUFaceRef. If I had an SUFaceRef, I could get at the SUEdgeRefs to set the layers, but I don’t see how use SUFaceRefs in conjunction with SUGeometryInputRefs.), is there a reason why the edges in the loops that are used to create the face don’t have their layers set by the same function?

I use SULoopInputEdgeSetSoft and SULoopInputEdgeSetSmooth to set values on the edges in the loop, maybe you can add an additional function that will let you set the layer.

If you need to see the source code let me know and I can send it.

Tim


#7

Lemme ping @bugra and @Paul


#8

Sorry, I didn’t see this thread before today. I am not really sure if the layer mismatch between edges and faces is what’s causing the strange disconnected behavior. It is also possible that separate vertices are being created at the corners. Though they would have to be physically separated enough so they wouldn’t get merged together.

@tim: It seems our API is a bit lacking here. We could certainly use a SULoopInputEdgeSetLayer. I think the reason it doesn’t automatically assume the face layer is that it could be ambiguous for shared edges. One workaround would be to create the geometry on the default layer, then get them all from the SUEntitiesRef and set their layers separately.

I will make a note to add this function to the API. Thank you for the heads-up !
If you’d like to share any code, don’t hesitate to send me a PM.


#9

Hi Bugra,

The 3d locations of the vertexes, at the corner of a box for instance, should be identical. Each loop would have a distinct index for one of three identical points. I will hook it up today so that the loops use one index/vertex and see if it makes a difference. I’ll let you know. If it doesn’t, I’ll send you the plugin code so you can have a look.

Tim


#10

Hi Bugra,

Using a single vertex and index for each distinct location appears to have fixed the weird face issue that started this thread. Thanks for the tip.

It would still be nice to have an SULoopInputEdgeSetLayer function. With that I can set the layer for the edges at the time I create the face, while I have all the attributes at hand (material, layer, grouping, etc.). If I have to use the SUEntitiesRef after calling SUEntitiesFill I’ll have to do some bookkeeping to keep things straight. Not the end of the world but more work than is necessary. Although, it looks like having edges on Layer0 (since they’re not explicitly set to something else) and faces on whatever layer they were on in Rhino does not seem to have an impact good or bad on the “crazy face problem”.

Tim


#11

Tim, I recorded it in our system to add SULoopInputEdgeSetLayer. But it’s curious that duplicate vertices don’t properly get merged, we may have a bug there. I’ll file that too. But it would be fastest to use shared vertex indices anyway, like you did. I’m glad it’s resolved.


#12

3d predicted that in the export file with accidental or ungroup or have in the making in the form of 2D, so that when imported into SketchUp program has been lost or suffered a split …
may be useful


#13

I was running into this problem too, so a SULoopInputEdgeSetLayer function would be really useful.

I did manually work around it using the following code after I had called SUEntitiesFill, but it was horrendously slow for some reason:

size_t edgeCount = 0;
SUEntitiesGetNumEdges( entities, false, &edgeCount );
std::vector<SUEdgeRef> edges( edgeCount );
SUEntitiesGetEdges( entities, false, edgeCount, &edges[ 0 ], &edgeCount );
for ( auto iter = edges.begin(); iter != edges.end(); iter++ ) {
	SUDrawingElementRef edge = SUEdgeToDrawingElement( *iter );
	if ( SUIsValid( edge ) ) {
		SUDrawingElementSetLayer( edge, layerRef );
	}
}

James


#14

In release build? Did you run it through a profiler?


#15

I did run a performance analysis in release build (in Visual Studio 2012), and it’s sitting in the SUDrawingElementSetLayer call (99% of which is spent in __tmainCRTStartup, so I may have another issue).

Thanks,
James


#16

I’d like to bring the SUDrawingElementSetLayer issue back into the spotlight.

Exporting a model of a kindergarten chair from Rhino (I can provide both the original .3dm (~1.5mb) and the .skp output file (~2.2Mb) if it will help) to Sketchup took 4 minutes and 31 seconds. Running the same test with everything exactly the same, only the SUDrawingElementSetLayer line commented out took 3 seconds. I’m using SDK version 16.0.19912.0 and here is a snippet of the code where the line is commented out.

for (i = 0; facect > i; i++)
{
  SUDrawingElementRef FaceDE = SUFaceToDrawingElement(faces[i]);

  facelayer = SU_INVALID;
  m_SUResult =  SUDrawingElementGetLayer(FaceDE, &facelayer);
  if (SU_ERROR_NONE != m_SUResult)
    return false;

  facematerial = SU_INVALID;
  m_SUResult = SUDrawingElementGetMaterial(FaceDE, &facematerial);
  if (SU_ERROR_NONE != m_SUResult && SU_ERROR_NO_DATA != m_SUResult)
    return false;

  m_SUResult = SUFaceGetNumEdges(faces[i], &ct);
  if (SU_ERROR_NONE != m_SUResult)
    return false;

  std::vector<SUEdgeRef> edges;
  edges.resize(ct);
  m_SUResult = SUFaceGetEdges(faces[i], ct, &edges[0], &edgect);
  if (SU_ERROR_NONE != m_SUResult)
    return false;

  for (j = 0; edgect > j; j++)
  {
    SUDrawingElementRef EdgeDE = SUEdgeToDrawingElement(edges[j]);
    if (nullptr != facelayer.ptr)
    {
      //m_SUResult = SUDrawingElementSetLayer(EdgeDE, facelayer);  /////////////////////////////commented code
      if (SU_ERROR_NONE != m_SUResult)
        return false;
    }

    if (nullptr != facematerial.ptr)
    {
      m_SUResult = SUDrawingElementSetMaterial(EdgeDE, facematerial);
      if (SU_ERROR_NONE != m_SUResult)
        return false;
    }
  }
}

Incidentally, the same code (for the most part, a few things have changed on the Rhino side but the SketchUp side is virtually identical) on the Mac (but using the first Mac SDK available from Trimble) does not have this issue. I’m using the current SDK for our next Mac version but it’s (Rhino that is, not the export plugin) in a state where I can test at the moment.

Are you, James, or anyone else still seeing this?

Cheers,
Tim