Page 1 of 2

How to draw *.stl using my Plugin window

Posted: Tue May 17, 2016 7:09 am
by Eiji Kurihara
I know that if we use File -> Open ->STL mesh(*.stl), I can draw *.stl file on your CloudCompare Screen Window.
Now I am challenging to draw *.stl file from my Plugin.
Using ccHObject* newGroup = FileIOFilter::LoadFromFile(selectedFiles[0], parameters, currentFilter),
I can get "[I/O] File "***.stl" loaded successfully" message on the console window.
But newGroup->showColors( true ) ;
win->addToOwnDB( newGroup ) ;
win->zoomGlobal() ;
I cannot get any *.stl image on the CloudCompare Screen Window.
Please teach me how to draw *.stl file from myPlugin menu.
Sincerely,

Re: How to draw *.stl using my Plugin window

Posted: Tue May 17, 2016 6:45 pm
by daniel
You have to set your plugin display (win) as the default display for the entities. And in your case you have to add the entities to the display database as they are not in CloudCompare's main database:

Code: Select all

newGroup->setDisplay_recursive(win);
win->addToOwnDB(newGroup, true);
The second parameter of 'addToOwnDB' (boolean) tells whether the display will manage the pointer or not (if yes, then the entities will be destroyed when they are removed from the display, or when the display is deleted - otherwise you'll have to delete the entities yourself after having removed them from the display).

Moreover, the first time you add entities to the display, you'll have to update the zoom (with 'ccGLWindow::zoomGlobal' for instance).

Re: How to draw *.stl using my Plugin window

Posted: Wed May 18, 2016 12:36 am
by Eiji Kurihara
Dear Daniel,
Thank you for your reply. Inserting only
newGroup->setDisplay_recursive( win ) ;
I can display *.stl files in my plugin menu.
For this, I can evaluate the *.stl reading and displaying time interval.
Thank you very much.
Sincerely Yours,

Re: How to draw *.stl using my Plugin window

Posted: Wed May 18, 2016 10:19 am
by Eiji Kurihara
Now, I am trying to save the *.stl image made in my Plugin.
With the following code
STLFilter *filter = new STLFilter() ;
QString selectedFilter = filter->GetFileFilter() ;
ccHObject *entity = win->getOwnDB() ;
result = FileIOFilter::SaveToFile( entity ,outputFilename,parameters,selectedFilter);
there is an error message such as
"An error occurred while saving '****.stl': incompatible entity/file types",
, and I cannot save it in a new *.stl file.
Please tell me how to fix this program.
Sincerely,

Re: How to draw *.stl using my Plugin window

Posted: Wed May 18, 2016 11:26 am
by daniel
First you don't need to use the generic 'FileIOFilter::SaveToFile' if you know exactly the filter you want to use.

And pay attention that GetFileFilter is a static method (you don't need to call it on an instance).

And last but not least, make sure to pass a mesh entity to the filter. You can't save a group of objects in an STL file (this is what getOwnDB returns).

Your code should look like this:

Code: Select all

ccHObject::Container meshes;
if (win->getOwnDB()->filterChildren(meshes, false, CC_TYPES::MESH, false) != 0)
{
   //save the first mesh by default (you should make sure that there's only one mesh, or otherwise let the user choose the right one)
    STLFilter filter;
    filter.saveToFile(meshes[0], outputFilename, parameters);
}

Re: How to draw *.stl using my Plugin window

Posted: Thu May 19, 2016 1:49 am
by Eiji Kurihara
I just imitate your code.
QSettings settings;
settings.beginGroup(ccPS::SaveFile());
QString currentPath = settings.value(ccPS::CurrentPath(),QApplication::applicationDirPath()).toString();

QString outputFilename = QFileDialog::getSaveFileName(win, "Select *.stl output file", currentPath, "*.stl");
if (outputFilename.isEmpty()) {
return;
}
CC_FILE_ERROR result = CC_FERR_NO_ERROR;
FileIOFilter::SaveParameters parameters;
{
parameters.alwaysDisplaySaveDialog = true;
parameters.parentWidget = win;
}

float tm = clock() ;
char str[1024] ;
ccHObject::Container meshes;
if( win->getOwnDB()->filterChildren( meshes, false, CC_TYPES::MESH, false ) != 0 ) {
//save the first mesh by default (you should make sure that there's only one mesh, or otherwise let the user choose the right one)
STLFilter filter ;
result = filter.saveToFile( meshes[0], outputFilename, parameters ) ;
}
sprintf( str, "Time: %f sec.", (clock()-tm)/(float)CLOCKS_PER_SEC ) ;
app->dispToConsole( str ) ;

if (result != CC_FERR_NO_ERROR)
{
FileIOFilter::DisplayErrorMessage(result,"saving",outputFilename);
}
else
{
ccLog::Print(QString("[I/O] File '%1' saved successfully").arg(outputFilename));
}

//we update current file path
currentPath = QFileInfo(outputFilename).absolutePath();
settings.setValue(ccPS::CurrentPath(),currentPath);
settings.endGroup();

and getting the message
[10:13:05] [I/O] File 'C:/Users/kuri/SaneiMMS/STL_DATA/tt2.stl' saved successfully.

But tt2.stl file is not made anywhere. What is wrong about?
Sincerely,

Re: How to draw *.stl using my Plugin window

Posted: Thu May 19, 2016 3:13 am
by Eiji Kurihara
Dear Sir,
I found that "win->getOwnDB()->filterChildren( meshes, false, CC_TYPES::MESH, false )" return 0 .
So "filter.saveToFile( meshes[0], outputFilename, parameters ) ; " is not called.
The win is gotten by "ccGLWindow * win = m_app->getActiveGLWindow() ;"
So I think win is different from "*.stl image displayed window".
So how to get a displayed window to save ",stl displayed image"?
The *.stl displayed image and image *stl save command are called by different my_plugin command.
Please give me a good advice.
Sincerely,

Re: How to draw *.stl using my Plugin window

Posted: Thu May 19, 2016 8:38 am
by Eiji Kurihara
Dear Daniel,

By changing the second recursive parameter
if( win->getOwnDB()->filterChildren( meshes, true, CC_TYPES::MESH, false ) != 0 ) {
from false to true ,
I can save a new *stl file. Also doing
ObjFilter filter ;
result = filter.saveToFile( meshes[0], outputFilename, parameters ) ;
I can save a old *stl image to a new *.obj file.
I don't know why it works.
But anyway, my problem is solved.
Thank you.

Re: How to draw *.stl using my Plugin window

Posted: Thu May 19, 2016 11:32 am
by daniel
I'm not sure to understand how the file is loaded and how it is saved.

By default the normal process would be to load the file via the main CloudCompare application. Then select the mesh and start your plugin. This way the mesh is in the central data base, accessible by everyone, and the user can save the mesh also with the main CloudCompare application.

If you load the mesh in your plugin, then either you add it to the main database (but it won't be interesting as you'd better do it as I described above) or you add it as a member of your plugin (or equivalently to the data base of a 3D view dedicated to your plugin). This way you can access the mesh either directly or via this dedicated 3D view. But you shouldn't use CloudCompare's 3D views for this.

To help you debug your plugin it may be easier to put it on github and let me look at the code. Don't hesitate also to send me emails directly (it's faster than the forum).

Re: How to draw *.stl using my Plugin window

Posted: Thu May 19, 2016 12:04 pm
by daniel
In your particular example, I think it's because the mesh was not added directly to the window database, but it was inside a group (the default container returned by the filter). Therefore if you look for the mesh in a recursive way you can always find the mesh... however you have to be sure that it's the only mesh that is currently displayed this way.

And anyway I wouldn't recommend to work as you currently do (see my previous post).