I am pretty much beginner in Sketchup programming. Working on generating a custom building model programmatically using C API. To generate wall faces with several opening on it I am using “SUGeometryInputAddFace” method as below
size_t outerLoopIndex;
result = SUGeometryInputAddFace(input, &loop, &outerLoopIndex);
That is working fine and I also need to attache attribute dictionary with the faces. It seems SUEntityGetAttributeDictionary does not work with SUGeometryInputRef. Is there a work around? Is there any function that convert the SUGeometryInputRef to SUEntityRef?
I am trying the following code that does not work.
SUResult result = SU_ERROR_NONE;
SUAttributeDictionaryRef dictionary = SU_INVALID;
Result = SUEntityGetAttributeDictionary(input, "mydictionary", dictionary);
I will highly appreciate any suggestion, workaround or example code.
SUGeometryInputRef is a virtual geometry build context. The objects created using it do not become SUEntityRef or SUDrawingElementRef subclass objects until after they have been added to the model.
SUFaceCreate and SUFaceCreateSimple should not be used - it doesn’t merge vertices, which is a requirement of a well formed SketchUp model. If for instance you try to create a cube with SUFaceCreate you’ll have overlapping vertices and edge. (There is a Bug warning in the docs for both of these functions.)
This means it’s hard to assign properties to created geometry via the C API unless SUGeometryInputRef doesn’t support it.
You might be able to apply the same workaround that is some times done in the Ruby API with Geom::PolygonMesh; if the input order of the faces to SUGeometryInputRef matches the iteration order of SUEntitiesGetFaces. Note that it’s a fragile workaround as it’s implementation detail. But until we have better API for this it might be your best (only) choice.
Dan/Thomas, Thank you very much to both of you for replying my question. I could able to get an work around the issue. It is in the same line what you had mentioned. Here is the code snippet that I used.
//SUGeometryInputRef geominput = SU_INVALID;
// Geometry creation code goes here
......
......
// Add the face to the entities collection
result = SUEntitiesFill(localEntities, geominput, true);
// Get all the faces from the entities object
SUAttributeDictionaryRef dictionary = SU_INVALID;
size_t faceCount = 0;
SUEntitiesGetNumFaces(localEntities, &faceCount);
if (faceCount > 0) {
std::vector<SUFaceRef> faces(faceCount);
SUEntitiesGetFaces(localEntities, faceCount, &faces[0], &faceCount);
// Get the last created face and convert to an entity.
SUEntityRef entity = SUFaceToEntity(faces[faceCount - 1]);
result = SUEntityGetAttributeDictionary(entity, "mydictionary", &dictionary);
SUTypedValueRef myvalue = SU_INVALID;
result = SUTypedValueCreate(&myvalue);
result = SUTypedValueSetString(myvalue, tagname.c_str());
result = SUAttributeDictionarySetValue(dictionary, "plane_type_override", myvalue);
result = SUTypedValueRelease(&myvalue);
}
// Release the geometry input
result = SUGeometryInputRelease(&geominput);
I could not use SUFaceCreateSimple for creating face because I need to put the holes into the face. Not found any better way to do that. Well, this one is kind a crude way and I am sure there could be a much better way to assign Attribute to face. However, I still believe including a overloaded method below in the API could make life much easier.
I will really appreciate if you could please recommend me any book or tutorial with lots of example code, particularly for using C API. I am a total beginner in the SketchUp application.
It is C. C compilers do not support overloading well (if at all.)
Also the entire SketchUp C API is written so that you must cast your subclass entity to a SUEntityRef in order to use the dictionary methods.
As I said above … SUGeometryInputRef is not a subclass of SUEntityRef (in the C++ core of SketchUp.) So it itself cannot be upcast to SUEntityRef.
Further, as mentioned SUGeometryInputRef is not an entity-like object, it’s a collection object. It is kind of like a temporary group that you add new geometry to, and when done it is merged with a SUEntitiesRef collection object.
So, what needs to happen is SUGeometryInputRef needs to get it’s own “wrapper” functions that allow attachment and modification of dictionaries to the “virtual” geometric objects within (ie, edges, faces, vertices, arcs, curves, etc.)
But those objects are not yet SUEntityRef subclass objects, so they must be accessed by index.
We’ve been talking within the team about investing more time in examples etc. Meanwhile, feel free to ask here on the forum and we’ll try our best to respond.