Thursday, November 30, 2023
Home3D ModelingDoes CAPI assist multi-threading? - SketchUp SDK

Does CAPI assist multi-threading? – SketchUp SDK


When outputting Structure, I need to generate mannequin viewports in a number of threads.

SDK_version: SDK_WIN_x64_2022-0-354
Supply Code: source_code.zip (2.1 KB)
Check file:test3.skp

I acquired exception from SketchupViewerAPI.dll

Unhandled exception at 0x00007FFFE69EBBF5(SketchUpViewerAPI.dll)(SketchUpTest.exe):There’s a battle when learn Handle 0xFFFFFFFFFFFFFFFF.

image

#embody<LayOutAPIlayout.h>
#embody<SketchUpAPIsketchup.h>
#embody<assert.h>
#embody<string>
#embody<cstdio>
#embody<vector>
#embody"threadpool.h"

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

std::mutex _lockAddEntity;

int important() {
	std::string skp_file = "F:/Desktop/relation_skp/test3.skp";

	LOInitialize();
	LODocumentRef doc = SU_INVALID;
	SU(LODocumentCreateEmpty(&doc));

	LOLayerRef layer = SU_INVALID;
	SU(LODocumentGetLayerAtIndex(doc, 0, &layer));

	LOPageRef web page = SU_INVALID;
	SU(LODocumentGetPageAtIndex(doc, 0, &web page));

	ThreadPool pool(4);

	std::vector<std::future<int>> executors;
	// test3.skp have 43 pages.  page1 - page43
	int num_of_out_page = 43; // It is okay when num_of_out_page=4.
	for (int i = 0; i < num_of_out_page; i++) {
		executors.emplace_back(pool.enqueue([&document, skp_file, i] {

			std::string page_name = "web page";
			char num_str[3] = { 0 };
			itoa(i + 1, num_str, 10);
			page_name.append(num_str);

			LOAxisAlignedRect2D rect;  // (0,0)  (5,5)
			rect.upper_left.x = rect.upper_left.y = 0;
			rect.lower_right.x = rect.lower_right.y = 5;
			LOSketchUpModelRef mannequin = SU_INVALID;

			SUResult res = LOSketchUpModelCreate(&mannequin, skp_file.c_str(), &rect);
			if (res == SU_ERROR_NONE) {
				std::unique_lock<std::mutex> lock{ _lockAddEntity };  // lock AddEntity

				res = LODocumentAddEntityUsingIndexes(doc, LOSketchUpModelToEntity(mannequin), 0, 0);
				if (res == SU_ERROR_NONE) {
					res = LOSketchUpModelSetCurrentScene(mannequin, i + 1);
					if (res == SU_ERROR_NONE)
						printf("%d %s okn", i, page_name.c_str());
					else
						printf("%d %s SetScene Error %dn", i, page_name.c_str(), res);
				}
				else
					printf("%d %s AddEntity Error %dn", i, page_name.c_str(), res);

				lock.unlock();  // unlock AddEntity

				SU(LOSketchUpModelRelease(&mannequin));  // launch SketchUpModel
			}
			else {
				printf("%d %s Create Error %dn", i, page_name.c_str(), res);
			}
			return i;
		}));
	}

	// important thread wait all executor
	for (auto && executor : executors)
		executor.get();

	SU(LODocumentSaveToFile(doc, "F:/Desktop/relation_skp/take a look at.format", LODocumentVersion_Current));
	SU(LODocumentRelease(&doc));

	LOTerminate();
	printf("finishn");
	return 0;
}


We can not translate Chinese language from a picture. Please put up an English translation of the exception message.

Is skp_file the identical for all viewports ?

How would a number of threads be capable of learn from the identical file (or it’s illustration in reminiscence) and be capable of write to the identical reminiscence illustration of a LayOut doc, on the identical time ?


Additionally I don’t see that you simply’ve added the viewport to the LayOut doc throughout the loop.
See: LODocumentAddEntity()

Typically, with the LayOut APIs, the entity must be first connected to a doc earlier than it’s properties might be modified. In any other case the entity’s properties get set to default values.

Unhandled exception at 0x00007FFFE69EBBF5(SketchUpViewerAPI.dll)(SketchUpTest.exe):There’s a battle when learn Handle 0xFFFFFFFFFFFFFFFF.
SketchUpTest is my program.

Sure, It’s identical file.

In my creativeness, multithreaded studying needs to be okay, as a result of it doesn’t contain writing.

If the identical file exists in SketchupViewAPI.dll, and the SKP file is parsed solely as soon as and there’s an operation to write down to reminiscence, the API might not be relevant to a number of threads.

You might be proper. My focus is on the LOSketchUpModelCreate.
And I need take a look at it, as a result of the perform is time-consuming.

I replace.

What an fascinating query you’ve got requested. Whereas I doubt that the API was meant for use on this method, I discover that it’s doable to create the LOSketchupModelRefs in parallel, vastly decreasing the time wanted to provide the format file. I absolutely anticipate somebody from SU to say it is a dangerous concept!

The code under appears to work with ‘trendy’ Sketchup recordsdata whereas failing for older variations.

#embody<LayOutAPIlayout.h>
#embody <assert.h>
#embody<string>
#embody<cstdio>
#embody<vector>
#embody"threadpool.h"
//#embody <conio.h>

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

std::mutex _lockAddEntity;

int important() {
	std::string skp_file = "C:/Customers/person/Desktop/test3.skp";

	LOInitialize();

	// Create a vector of LOSketchUpModelRefs utilizing a thread pool
	// 
	int num_of_out_page = 25;
	std::vector<LOSketchUpModelRef> fashions(num_of_out_page, SU_INVALID);

	ThreadPool pool(4);
	std::vector<std::future<int>> executors;

	for (int i = 0; i < num_of_out_page; i++) { 
		printf("Queueing: %dn", i);

		LOSketchUpModelRef*  mannequin = &fashions[i];
		executors.emplace_back(pool.enqueue([ model, skp_file,  i] {
			
			LOAxisAlignedRect2D rect;  // (0,0)  (5,5)
			rect.upper_left.x = rect.upper_left.y = 0.2;
			rect.lower_right.x = 10.8;
			rect.lower_right.y = 7.8;

			SUResult res = LOSketchUpModelCreate(mannequin, skp_file.c_str(), &rect);
			if (res == SU_ERROR_NONE) {
				printf("Created %dn", i);
			}
			else
			{
				printf("%d Create Error %dn", i, res);
			}
			return i;
			}));
	}

	// important thread wait all executors
	for (auto&& executor : executors)
		executor.get();

	// It's informative to cease right here and take a look at the reminiscence use.
	// To take action, uncomment these strains and #embody <conio.h>
	// In Visible Studio open Debug>Home windows>Diagnostic Instruments
	// 
	//printf("The Fashions have been created. Press any key to proceed.");
	//int chr = _getch();
	//printf("n");

	// Add fashions to the Structure doc
	LODocumentRef doc = SU_INVALID;
	SU(LODocumentCreateEmpty(&doc));

	for (int i = 0; i < num_of_out_page; i++) {

		LOPageRef page_ref = SU_INVALID;
		if (i < 1)
			LODocumentGetPageAtIndex(doc, i, &page_ref);
		else
			LODocumentAddPage(doc, &page_ref);

		// Set the page_ref title right here!!!

		SUResult res;
		res = LOSketchUpModelSetCurrentScene(fashions[i], i + (size_t)1);
		if (res == SU_ERROR_NONE)
		{
			//printf("Scene Set: %dn", i);
		}
		else
		{
			printf("SetScene Failed: %dn", i);
		}

		res = LODocumentAddEntityUsingIndexes(doc, LOSketchUpModelToEntity(fashions[i]), 0, i);
		if (res == SU_ERROR_NONE) 
		{
			printf("Added: %dn", i);
		}
		else
		{
			printf("Add Failed: %dn", i);
		}
	}

	SU(LODocumentSaveToFile(doc, "C:/Customers/person/Desktop/test3.format", LODocumentVersion_Current));
	SU(LODocumentRelease(&doc));
	
	//for (int i = 0; i < num_of_out_page; i++) { SU(LOSketchUpModelRelease(&fashions[i])); }  // launch SketchUpModel

	LOTerminate();
	printf("Completedn");
	return 0;
}

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments