How to create a hole using the inner loop?

I’m using C SDK to build a custom exporter for room plans. The holes desired to represent positions for windows/doors object.

My current algorithm looks like this:

  • Create an outer loop SULoopInputCreate;
  • Add outer loop vertices SUGeometryInputAddVertex, SULoopInputAddVertexIndex;
  • Add face SUGeometryInputAddFace;
  • Create inner loop SULoopInputCreate;
  • Add inner loop vertices SUGeometryInputAddVertex, SULoopInputAddVertexIndex;
  • Add inner loop to the face SUGeometryInputFaceAddInnerLoop.

The result of the algorithm: inner loop vertices are on the place but the inner area has the same face as an outer area. I’m looking for a way to cut a hole in the outer area.

See the image for a visual representation.
Capture3

Thanks in advance!

1 Like
 enum SUResult SUFaceAddInnerLoop(SUFaceRef face,const struct SUPoint3D	vertices3d[],SULoopInputRef * loop )	

That doesn’t work with SUGeometryInput.

SUGeometryInputFaceAddInnerLoop is the correct method to use.

I am not able to reproduce the behaviour you describe. I wrote a small test:

// SLAPI-Test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <assert.h>
#include <iostream>
#include <vector>

#include "SketchUpAPI/sketchup.h"

#define SU(api_function_call) {\
  SUResult su_api_result = api_function_call;\
  assert(SU_ERROR_NONE == su_api_result);\
}\

#define refute(condition) assert(!(condition))


std::string GetString(const SUStringRef& string) {
  size_t length = 0;
  SU(SUStringGetUTF8Length(string, &length));
  std::vector<char> buffer(length + 1);
  size_t out_length = 0;
  SU(SUStringGetUTF8(string, length + 1, buffer.data(), &out_length));
  assert(out_length == length);
  return std::string(begin(buffer), end(buffer));
}


int _tmain(int argc, _TCHAR* argv[])
{
  std::string project_path = "C:\\Users\\tthomas2\\SourceTree\\SLAPI-Test";
  std::string model_path = project_path + "\\models\\SU-XXXXX.skp";
  std::string temp_path = project_path + "\\temp";
  std::string temp_model_path = temp_path + "\\SUGeometryInput.skp";

  SUInitialize();

  SUModelRef model = SU_INVALID;
  SU(SUModelCreate(&model));
  //SU(SUModelCreateFromFile(&model, model_path.c_str()));

  SUEntitiesRef entities = SU_INVALID;
  SU(SUModelGetEntities(model, &entities));

  SUGeometryInputRef input = SU_INVALID;
  SU(SUGeometryInputCreate(&input));


  std::vector<SUPoint3D> points{
    // Outer loop
    { 0.0, 0.0, 0.0 }, 
    { 9.0, 0.0, 0.0 }, 
    { 9.0, 9.0, 0.0 }, 
    { 0.0, 9.0, 0.0 },
    // Inner loop
    { 2.0, 2.0, 0.0 },
    { 7.0, 2.0, 0.0 },
    { 7.0, 7.0, 0.0 },
    { 2.0, 7.0, 0.0 },
  };
  for (const auto& point : points) {
    SU(SUGeometryInputAddVertex(input, &point));
  }


  // Outer loop
  SULoopInputRef outer_loop = SU_INVALID;
  SULoopInputCreate(&outer_loop);
  for (size_t i = 0; i < 4; ++i) {
    SU(SULoopInputAddVertexIndex(outer_loop, i));
  }
  size_t face_index = 0;
  SU(SUGeometryInputAddFace(input, &outer_loop, &face_index));

  // Inner loop
  SULoopInputRef inner_loop = SU_INVALID;
  SULoopInputCreate(&inner_loop);
  for (size_t i = 4; i < 8; ++i) {
    SU(SULoopInputAddVertexIndex(inner_loop, i));
  }
  SU(SUGeometryInputFaceAddInnerLoop(input, face_index, &inner_loop))


  SU(SUEntitiesFill(entities, input, true));

  SU(SUGeometryInputRelease(&input));

  SU(SUModelSaveToFile(model, temp_model_path.c_str()));

  SU(SUModelRelease(&model));

  SUTerminate();
  return 0;
}

That produced a face with a hole.

I’d recommend you double check the return values of your calls to the SU API in case you are getting errors at some point.

If you still experience problems, please distill it down to a self contained code example similar to my example above.

2 Likes

Yes, u are right.
I didn’t look at the problem carefully.