[Sketchup C API]Howto merge models oftwo .skp files into one
-
Assumption: My models contain only ComponentInstances.
My Approach:
- Get the models of each of the file, say m1,m2 (using
SUModelCreateFromFile). - Get entities of m1 and m2, say e1,e2 (using
SUModelGetEntities). - Get ComponentInstances from e2 (using
SUEntitiesGetInstances). - In a loop add each of the ComponentInstance of e2 into e1 (using
SUEntitiesAddInstance). - Write the model m1(with entities e1) to a new file.
//The new file contains the ComponentInstances of m1,m2.
Where I am stuck?
In the below code.On a high level the below program does three things
- It gets the Model from file.
- From Model it gets Entities.
- From Entitites it gets ComponentInstances. Here it fails.
#include <slapi/slapi.h> #include <slapi/geometry.h> #include <slapi/initialize.h> #include <slapi/model/model.h> #include <slapi/model/entities.h> #include <slapi/model/face.h> #include <slapi/model/edge.h> #include <slapi/model/vertex.h> #include <vector> #include <iostream> #include <stdio.h> int main() { // Always initialize the API before using it SUInitialize(); // Load the model from a file SUModelRef model_to_write1 = SU_INVALID; SUResult m1 = SUModelCreateFromFile(&model_to_write1, "model11.skp"); if(m1 == SU_ERROR_NONE) std;;cout<<"SUModelCreateFromFile SUCCESS!!!!!"; else if(m1 == SU_ERROR_NULL_POINTER_INPUT) std;;cout<<"Error_Entities -- Inside 1 file are"; else if(m1 == SU_ERROR_NULL_POINTER_OUTPUT) std;;cout<<"NULLPOINTER_Entities -- Inside 1 file are"; else printf("None of the above"); SUEntitiesRef entities1 = SU_INVALID; size_t* size1 = NULL; SUComponentInstanceRef comp1[10]; SUResult result = SUModelGetEntities(model_to_write1, &entities1); if(result == SU_ERROR_NONE) std;;cout<<"\n SUModelGetEntities SUCCESS !!!!!"; if(result == SU_ERROR_INVALID_INPUT) std;;cout<<"Error_Entities Inside 1 file are"; if(result == SU_ERROR_NULL_POINTER_OUTPUT) std;;cout<<"NULLPOINTER_Entities Inside 1 file are"; result = SUEntitiesGetInstances(entities1,2,comp1,size1); if(result == SU_ERROR_NONE) std;;cout<<"\n SUEntitiesGetInstances SUCCESS"; else if(result == SU_ERROR_INVALID_INPUT) std;;cout<<"\n Error_Copy"; else if(result == SU_ERROR_NULL_POINTER_OUTPUT) std;;cout<<"\n NULLPOINTER"; // Save the in-memory model to a file SUModelSaveToFile(model_to_write1, "very_new_model.skp"); SUTerminate(); getchar(); return 0; }Output:
SUModelCreateFromFile SUCCESS!!!!!
SUModelGetEntities SUCCESS !!!!!
NULLPOINTERQuestions:
- In the above output I am getting NULLPOINTER(3rd line) which is the result of call
SUEntitiesGetInstances(entities1,2,comp1,size1)in the above program. Why I am not able to get the ComponentInstances? - Can you please review the approach which is mentioned at the beginning and let me know if is it right?
- Get the models of each of the file, say m1,m2 (using
-
The error is that you are passing a NULL pointer as the count argument to SUEntitiesGetInstances. You should pass a reference to an initialized value:
size_t instanceCount = 0; SUEntitiesGetNumInstances(entities1, &instanceCount); std;;vector<SUComponentInstanceRef> instances(instanceCount); size_t count = 0; result = SUEntitiesGetInstances(entities1, instanceCount, &instances[0], &count);Full snippet:
#include <slapi/slapi.h> #include <slapi/geometry.h> #include <slapi/initialize.h> #include <slapi/model/model.h> #include <slapi/model/entities.h> #include <slapi/model/face.h> #include <slapi/model/edge.h> #include <slapi/model/vertex.h> #include <vector> #include <iostream> #include <stdio.h> int main() { // Always initialize the API before using it SUInitialize(); // Load the model from a file SUModelRef model_to_write1 = SU_INVALID; SUResult m1 = SUModelCreateFromFile(&model_to_write1, "model11.skp"); if(m1 == SU_ERROR_NONE) std;;cout << "SUModelCreateFromFile SUCCESS!!!!!" << std;;endl; else if(m1 == SU_ERROR_NULL_POINTER_INPUT) std;;cout << "Error_Entities -- Inside 1 file are" << std;;endl; else if(m1 == SU_ERROR_NULL_POINTER_OUTPUT) std;;cout << "NULLPOINTER_Entities -- Inside 1 file are" << std;;endl; else std;;cout << "None of the above; " << m1 << std;;endl; SUEntitiesRef entities1 = SU_INVALID; SUResult result = SUModelGetEntities(model_to_write1, &entities1); if(result == SU_ERROR_NONE) std;;cout << "SUModelGetEntities SUCCESS !!!!!" << std;;endl; if(result == SU_ERROR_INVALID_INPUT) std;;cout << "Error_Entities Inside 1 file are" << std;;endl; if(result == SU_ERROR_NULL_POINTER_OUTPUT) std;;cout << "NULLPOINTER_Entities Inside 1 file are" << std;;endl; size_t faceCount = 0; SUEntitiesGetNumFaces(entities1, &faceCount); if (faceCount > 0) { std;;vector<SUFaceRef> faces(faceCount); result = SUEntitiesGetFaces(entities1, faceCount, &faces[0], &faceCount); if(result == SU_ERROR_NONE) std;;cout << "SUEntitiesGetFaces SUCCESS" << std;;endl; else std;;cout << "SUEntitiesGetFaces Fail!" << std;;endl; } size_t instanceCount = 0; SUEntitiesGetNumInstances(entities1, &instanceCount); std;;vector<SUComponentInstanceRef> instances(instanceCount); size_t count = 0; result = SUEntitiesGetInstances(entities1, instanceCount, &instances[0], &count); if(result == SU_ERROR_NONE) std;;cout << "SUEntitiesGetInstances SUCCESS" << std;;endl; else if(result == SU_ERROR_INVALID_INPUT) std;;cout << "Error_Copy" << std;;endl; else if(result == SU_ERROR_NULL_POINTER_OUTPUT) std;;cout << "NULLPOINTER" << std;;endl; // Save the in-memory model to a file SUModelSaveToFile(model_to_write1, "very_new_model.skp"); SUTerminate(); getchar(); return 0; } -
Wouldn't the Component Definitions of m2 need to be loaded into m1, and then using the transforms of the instances from m2, new instances made within m1's entities, and then a new model file written out as m3 ?
-
Thank you Thomas. We got the whole thing working except for one small thing. We need your input for the same.
Problem: The files m1 and m2 which we want to merge to m3 - have the "Millimeters" units. But the merged file m3 gets saved with "Inches" units. I see that there is a way to get
SUModelGetUnitsfrom the model. But no method to Set the units for the model. Is there any method (any other indirect way) - such that the new file gets saved with "Millimeters" units?By the way the approach for merging is below and it works for us.
- Get the models of each of the file, say m1,m2.
- Get entities of m1 and m2, say e1,e2.
- Get Instances from e1 and e2, say i1, i2 ( assume we have 1 instance in each model)
- Get Definition of i1 and i2, say d1 and d2
- Create new instances of d1 and d2, ni1 and ni2
- Create a new empty model , say new_model
- Get the entities of new_model, say new_entities
- Now add ni1 and ni2 to new_entities
- Save the new_model to file
- Release the memory
We are yet to work on the transformations for merging
-
I'll check with the rest of the team on the unit issue.
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better đź’—
Register LoginAdvertisement