Added partial render ability to IDF plugin

This commit is contained in:
Cirilo Bernardo 2015-12-11 17:37:42 +11:00
parent b46451ec81
commit 86042d86a6
5 changed files with 266 additions and 42 deletions

View File

@ -21,6 +21,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
#define GLM_FORCE_RADIANS
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <cstdio> #include <cstdio>
@ -598,21 +600,24 @@ S3DMODEL* S3D_CACHE::Prepare( S3D_INFO const* aModelEntry,
return NULL; return NULL;
// create a single transform entity to apply to the models // create a single transform entity to apply to the models
glm::dmat4 t0 = glm::translate( glm::dvec3( 25.4 * aModelEntry->offset.x, 25.4 * aModelEntry->offset.y, glm::dmat4 t0 = glm::translate( glm::dvec3( 25.4 * aModelEntry->offset.x,
25.4 * aModelEntry->offset.z ) ); 25.4 * aModelEntry->offset.y, 25.4 * aModelEntry->offset.z ) );
glm::dmat4 rX = glm::rotate( aModelEntry->rotation.x, glm::dvec3( 1.0, 0.0, 0.0 ) ); glm::dmat4 rX = glm::rotate( glm::radians( aModelEntry->rotation.x ),
glm::dmat4 rY = glm::rotate( -aModelEntry->rotation.y, glm::dvec3( 0.0, 1.0, 0.0 ) ); glm::dvec3( 1.0, 0.0, 0.0 ) );
glm::dmat4 rZ = glm::rotate( aModelEntry->rotation.z, glm::dvec3( 0.0, 0.0, 1.0 ) ); glm::dmat4 rY = glm::rotate( glm::radians( -aModelEntry->rotation.y ),
glm::dvec3( 0.0, 1.0, 0.0 ) );
glm::dmat4 rZ = glm::rotate( glm::radians( aModelEntry->rotation.z ),
glm::dvec3( 0.0, 0.0, 1.0 ) );
glm::dmat4 s0 = glm::scale( glm::dvec3( aModelEntry->scale.x, aModelEntry->scale.y, glm::dmat4 s0 = glm::scale( glm::dvec3( aModelEntry->scale.x, aModelEntry->scale.y,
aModelEntry->scale.z ) ); aModelEntry->scale.z ) );
glm::dmat4 m0 = rZ * rY * rX * s0 * t0; glm::dmat4 m0 = rZ * rY * rX * s0 * t0;
rX = glm::rotate( aRotation.x, glm::dvec3( 1.0, 0.0, 0.0 ) ); rX = glm::rotate( glm::radians( aRotation.x ), glm::dvec3( 1.0, 0.0, 0.0 ) );
rY = glm::rotate( aRotation.y, glm::dvec3( 0.0, 1.0, 0.0 ) ); rY = glm::rotate( glm::radians( aRotation.y ), glm::dvec3( 0.0, 1.0, 0.0 ) );
rZ = glm::rotate( aRotation.z, glm::dvec3( 0.0, 0.0, 1.0 ) ); rZ = glm::rotate( glm::radians( aRotation.z ), glm::dvec3( 0.0, 0.0, 1.0 ) );
glm::dmat4 t1 = glm::translate( glm::dvec3( aOffset.x, aOffset.y, aOffset.z ) ); glm::dmat4 t1 = glm::translate( glm::dvec3( aOffset.x, aOffset.y, aOffset.z ) );

View File

@ -98,7 +98,7 @@ int S3D_PLUGIN_IDF::GetNFilters( void ) const
const wxString S3D_PLUGIN_IDF::GetFileFilter( int aIndex ) const const wxString S3D_PLUGIN_IDF::GetFileFilter( int aIndex ) const
{ {
if( aIndex < 0 || aIndex >= m_filters.size() ) if( aIndex < 0 || aIndex >= (int)m_filters.size() )
return wxEmptyString; return wxEmptyString;
return m_filters[aIndex]; return m_filters[aIndex];
@ -115,56 +115,91 @@ bool S3D_PLUGIN_IDF::CanRender( void ) const
SCENEGRAPH* S3D_PLUGIN_IDF::Load( const wxString& aFileName ) SCENEGRAPH* S3D_PLUGIN_IDF::Load( const wxString& aFileName )
{ {
// load and render the file // load and render the file
#warning TO BE IMPLEMENTED
IDF3_BOARD brd( IDF3::CAD_ELEC ); IDF3_BOARD brd( IDF3::CAD_ELEC );
IDF3_COMP_OUTLINE* outline = brd.GetComponentOutline( aFileName ); IDF3_COMP_OUTLINE* outline = brd.GetComponentOutline( aFileName );
if( NULL == outline ) if( NULL == outline )
return NULL;
// render the component outline
const std::map< std::string, IDF3_COMPONENT* >*const comp = brd.GetComponents();
size_t asize = comp->size();
if( 1 != asize )
{ {
#ifdef DEBUG #ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] unexpected number of components: " << asize << "\n"; std::cerr << " * [INFO] no outline for file '";
std::cerr << aFileName.ToUTF8() << "'\n";
#endif #endif
return NULL; return NULL;
} }
const std::list< IDF3_COMP_OUTLINE_DATA* >*
ip = comp[0].begin()->second->GetOutlinesData();
asize = ip->size();
if( 1 != asize )
{
#ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] unexpected number of outlines: " << asize << "\n";
#endif
return NULL;
}
IDF3_COMP_OUTLINE_DATA* dp = *( ip->begin() );
IDF3_COMP_OUTLINE* pout = (IDF3_COMP_OUTLINE*)( dp->GetOutline() );
VRML_LAYER vpcb; VRML_LAYER vpcb;
if( !PopulateVRML( vpcb, pout->GetOutlines() ) ) if( !PopulateVRML( vpcb, outline->GetOutlines() ) )
{ {
#ifdef DEBUG #ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n"; std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] no valid outline data\n"; std::cerr << " * [INFO] no valid outline data in '";
std::cerr << aFileName.ToUTF8() << "'\n";
#endif #endif
return NULL; return NULL;
} }
// XXX - TO BE IMPLEMENTED vpcb.Tesselate( NULL );
std::vector< double > vertices;
std::vector< int > indices;
double thick = outline->GetThickness();
if( !vpcb.Get3DTriangles( vertices, indices, thick, 0.0 ) )
{
#ifdef DEBUG
std::cerr << __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__ << "\n";
std::cerr << " * [INFO] no vertex data in '";
std::cerr << aFileName.ToUTF8() << "'\n";
#endif
return NULL; return NULL;
}
std::cerr << "XXX - Got " << vertices.size() / 3 << " vertices and " << indices.size() << " indices\n";
std::vector< SGPOINT > vlist;
size_t nvert = vertices.size() / 3;
size_t j = 0;
for( size_t i = 0; i < nvert; ++i, j+= 3 )
vlist.push_back( SGPOINT( vertices[j], vertices[j+1], vertices[j+2] ) );
// create the intermediate scenegraph
IFSG_TRANSFORM* tx0 = new IFSG_TRANSFORM( true );
IFSG_SHAPE* shape = new IFSG_SHAPE( *tx0 );
IFSG_FACESET* face = new IFSG_FACESET( *shape );
IFSG_COORDS* cp = new IFSG_COORDS( *face );
cp->SetCoordsList( nvert, &vlist[0] );
IFSG_COORDINDEX* coordIdx = new IFSG_COORDINDEX( *face );
coordIdx->SetIndices( indices.size(), &indices[0] );
// XXX - TO BE IMPLEMENTED : add correct normals and colors
std::vector< SGVECTOR > norms;
for( size_t i = 0; i < nvert; ++i )
norms.push_back( SGVECTOR( 0.0, 0.0, 1.0 ) );
IFSG_NORMALS* np = new IFSG_NORMALS( *face );
np->SetNormalList( nvert, &norms[0] );
// magenta
IFSG_APPEARANCE* material = new IFSG_APPEARANCE( *shape);
material->SetSpecular( 1.0, 0.0, 1.0 );
material->SetDiffuse( 0.9, 0.0, 0.9 );
material->SetAmbient( 0.9 );
material->SetShininess( 0.3 );
SCENEGRAPH* data = (SCENEGRAPH*)tx0->GetRawPtr();
// delete the API wrappers
delete shape;
delete face;
delete coordIdx;
delete material;
delete cp;
delete np;
delete tx0;
return data;
} }

View File

@ -155,10 +155,10 @@ SCENEGRAPH* S3D_PLUGIN_TETRA::Load( const wxString& aFileName )
// the vertex normals in this case are the normalized // the vertex normals in this case are the normalized
// vertex points // vertex points
SGVECTOR norm[4]; SGVECTOR norm[4];
norm[0] = SGVECTOR( -1.0, 0.0, SQ2 ); norm[0] = SGVECTOR( -1.0, 0.0, -SQ2 );
norm[1] = SGVECTOR( 1.0, 0.0, SQ2 ); norm[1] = SGVECTOR( 1.0, 0.0, -SQ2 );
norm[2] = SGVECTOR( 0.0, -1.0, -SQ2 ); norm[2] = SGVECTOR( 0.0, -1.0, SQ2 );
norm[3] = SGVECTOR( 0.0, 1.0, -SQ2 ); norm[3] = SGVECTOR( 0.0, 1.0, SQ2 );
IFSG_NORMALS* np = new IFSG_NORMALS( *face ); IFSG_NORMALS* np = new IFSG_NORMALS( *face );
np->SetNormalList( 4, norm ); np->SetNormalList( 4, norm );

View File

@ -1786,3 +1786,173 @@ void VRML_LAYER::SetVertexOffsets( double aXoffset, double aYoffset )
offsetY = aYoffset; offsetY = aYoffset;
return; return;
} }
bool VRML_LAYER::Get3DTriangles( std::vector< double >& aVertexList,
std::vector< int > &aIndexList, double aTopZ, double aBotZ )
{
aVertexList.clear();
aIndexList.clear();
if( ordmap.size() < 3 || outline.empty() )
return false;
if( aTopZ <= aBotZ )
{
double tmp = aBotZ;
aBotZ = aTopZ;
aTopZ = tmp;
}
VERTEX_3D* vp = getVertexByIndex( ordmap[0], pholes );
if( !vp )
return false;
size_t i, j, k;
size_t vsize = ordmap.size();
j = 0;
k = vsize;
// top vertices
for( i = 0; i < vsize; ++i )
{
vp = getVertexByIndex( ordmap[i], pholes );
if( !vp )
{
aVertexList.clear();
return false;
}
aVertexList.push_back( vp->x );
aVertexList.push_back( vp->y );
aVertexList.push_back( aTopZ );
}
// bottom vertices
for( i = 0; i < vsize; ++i )
{
vp = getVertexByIndex( ordmap[i], pholes );
aVertexList.push_back( vp->x );
aVertexList.push_back( vp->y );
aVertexList.push_back( aBotZ );
}
// create the index lists .. it is difficult to estimate the list size
// a priori so instead we use a vector to help
bool holes_only = triplets.empty();
if( !holes_only )
{
// go through the triplet list and write out the indices based on order
std::list< TRIPLET_3D >::const_iterator tbeg = triplets.begin();
std::list< TRIPLET_3D >::const_iterator tend = triplets.end();
while( tbeg != tend )
{
// top vertices
aIndexList.push_back( (int) tbeg->i1 );
aIndexList.push_back( (int) tbeg->i2 );
aIndexList.push_back( (int) tbeg->i3 );
// bottom vertices
aIndexList.push_back( (int) ( tbeg->i2 + vsize ) );
aIndexList.push_back( (int) ( tbeg->i1 + vsize ) );
aIndexList.push_back( (int) ( tbeg->i3 + vsize ) );
++tbeg;
}
}
// compile indices for the walls joining top to bottom
int lastPoint;
int curPoint;
int curContour = 0;
std::list< std::list< int >* >::const_iterator obeg = outline.begin();
std::list< std::list< int >* >::const_iterator oend = outline.end();
std::list< int >* cp;
std::list< int >::const_iterator cbeg;
std::list< int >::const_iterator cend;
i = 2;
while( obeg != oend )
{
cp = *obeg;
if( cp->size() < 3 )
{
++obeg;
++curContour;
continue;
}
cbeg = cp->begin();
cend = cp->end();
lastPoint = *(cbeg++);
while( cbeg != cend )
{
curPoint = *(cbeg++);
if( !holes_only )
{
aIndexList.push_back( curPoint );
aIndexList.push_back( lastPoint );
aIndexList.push_back( (int)( curPoint + vsize ) );
aIndexList.push_back( (int)( curPoint + vsize ) );
aIndexList.push_back( lastPoint );
aIndexList.push_back( (int)( lastPoint + vsize ) );
}
else
{
aIndexList.push_back( curPoint );
aIndexList.push_back( (int)( curPoint + vsize ) );
aIndexList.push_back( lastPoint );
aIndexList.push_back( (int)( curPoint + vsize ) );
aIndexList.push_back( (int)( lastPoint + vsize ) );
aIndexList.push_back( lastPoint );
}
lastPoint = curPoint;
}
// check if the loop needs to be closed
cbeg = cp->begin();
cend = --cp->end();
curPoint = *(cbeg);
lastPoint = *(cend);
if( !holes_only )
{
aIndexList.push_back( curPoint );
aIndexList.push_back( lastPoint );
aIndexList.push_back( (int)( curPoint + vsize ) );
aIndexList.push_back( (int)( curPoint + vsize ) );
aIndexList.push_back( lastPoint );
aIndexList.push_back( (int)( lastPoint + vsize ) );
}
else
{
aIndexList.push_back( curPoint );
aIndexList.push_back( (int)( curPoint + vsize ) );
aIndexList.push_back( lastPoint );
aIndexList.push_back( (int)( curPoint + vsize ) );
aIndexList.push_back( (int)( lastPoint + vsize ) );
aIndexList.push_back( lastPoint );
}
++obeg;
++curContour;
}
return true;
}

View File

@ -456,6 +456,20 @@ public:
const std::string& GetError( void ); const std::string& GetError( void );
void SetVertexOffsets( double aXoffset, double aYoffset ); void SetVertexOffsets( double aXoffset, double aYoffset );
/**
* Function Get3DTriangles
* Allocates and populates the 3D vertex and index lists with
* triangular vertices which may be used for rendering.
*
* @param aVertexList will store the vertices
* @param aIndexList will store the indices
* @param aTopZ is the top plane of the model
* @param aBotZ is the bottom plane of the model
*/
bool Get3DTriangles( std::vector< double >& aVertexList,
std::vector< int > &aIndexList, double aTopZ, double aBotZ );
}; };
#endif // VRML_LAYER_H #endif // VRML_LAYER_H