/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015 Cirilo Bernardo * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, you may find one here: * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * or you may search the http://www.gnu.org website for the version 2 license, * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include S3D_PLUGIN_TETRA::S3D_PLUGIN_TETRA() { m_extensions.push_back( wxString::FromUTF8Unchecked( "wrl" ) ); #ifdef _WIN32 // assume a case-insensitive file system m_filters.push_back( wxT( "VRML 1.0/2.0 (*.wrl)|*.wrl" ) ); #else // assume the filesystem is case sensitive m_extensions.push_back( wxString::FromUTF8Unchecked( "WRL" ) ); m_filters.push_back( wxT( "VRML 1.0/2.0 (*.wrl;*.WRL)|*.wrl;*.WRL" ) ); #endif return; } S3D_PLUGIN_TETRA::~S3D_PLUGIN_TETRA() { return; } int S3D_PLUGIN_TETRA::GetNExtensions( void ) const { return (int) m_extensions.size(); } const wxString S3D_PLUGIN_TETRA::GetModelExtension( int aIndex ) const { if( aIndex < 0 || aIndex >= (int) m_extensions.size() ) return wxString( "" ); return m_extensions[aIndex]; } int S3D_PLUGIN_TETRA::GetNFilters( void ) const { return (int)m_filters.size(); } const wxString S3D_PLUGIN_TETRA::GetFileFilter( int aIndex ) const { if( aIndex < 0 || aIndex >= (int)m_filters.size() ) return wxEmptyString; return m_filters[aIndex]; } bool S3D_PLUGIN_TETRA::CanRender( void ) const { return true; } SCENEGRAPH* S3D_PLUGIN_TETRA::Load( const wxString& aFileName ) { // For this demonstration we create a tetrahedron and // paint its faces Magenta Red Green Blue. Steps: // * Create a top level transform tx0 which represent the VRML file // * Create a child transform tx1, parent tx0, to define the tetrahedron // + Create 'shape' to define one facet // ++ Create a 'face' to hold vertices and indices // +++ Create 'cp' which is the coordinate list // +++ Create 'np' which is the per-vertex normals list // +++ Create 'coordIndex' which is the (triangular) vertex index list // for facet1 of the tetrahedron // ++ Create a 'material' to define the appearance of 'shape' // ** // + shape->NewNode() to define next facet // ++ face->NewNode() for a new facet // +++ Add Ref to 'cp' for coordinate list // +++ Add Ref to 'np' for normals list // +++ coordIndex->NewNode() for vertex index list of new facet // ++ material->NewNode() for material of new facet // + repeat twice from ** to produce last 2 facets // * Create a child transform tx2, parent tx0, for a referenced tetrahedron // + Set a translation and rotation so that this is distinct from tx1 // + Add Reference to tx1 // ALL DONE: we now have: // tx0 // - contains tx1 which contains all elements of a tetrahedron // - contains tx0 which contains a reference to tx1 and offsets it so // that it renders in a different position // create the top level transform; this will hold all other // scenegraph objects; a transform may hold other transforms and // shapes IFSG_TRANSFORM* tx0 = new IFSG_TRANSFORM( true ); // create the transform which will house the shapes IFSG_TRANSFORM* tx1 = new IFSG_TRANSFORM( tx0->GetRawPtr() ); // add a shape which we will use to define a tetrahedron; shapes // hold facesets and appearances IFSG_SHAPE* shape = new IFSG_SHAPE( *tx1 ); // add a faceset; these contain coordinate lists, coordinate indices, // vertex lists, vertex indices, and may also contain color lists and // their indices. IFSG_FACESET* face = new IFSG_FACESET( *shape ); // define the vertices of the tetrahedron double SQ2 = sqrt( 0.5 ); SGPOINT vert[4]; vert[0] = SGPOINT( 1.0, 0.0, -SQ2 ); vert[1] = SGPOINT( -1.0, 0.0, -SQ2 ); vert[2] = SGPOINT( 0.0, 1.0, SQ2 ); vert[3] = SGPOINT( 0.0, -1.0, SQ2 ); IFSG_COORDS* cp = new IFSG_COORDS( *face ); cp->SetCoordsList( 4, vert ); // coordinate indices - note: enforce triangles; // in real plugins where it is not necessarily possible // to determine which side a triangle is visible from, // 2 point orders must be specified for each triangle IFSG_COORDINDEX* coordIdx = new IFSG_COORDINDEX( *face ); int cidx[12] = { 0, 3, 1, 0, 2, 3, 1, 3, 2, 0, 1, 2 }; coordIdx->SetIndices( 3, cidx ); // the vertex normals in this case are the normalized // vertex points SGVECTOR norm[4]; norm[0] = SGVECTOR( -1.0, 0.0, -SQ2 ); norm[1] = SGVECTOR( 1.0, 0.0, -SQ2 ); norm[2] = SGVECTOR( 0.0, -1.0, SQ2 ); norm[3] = SGVECTOR( 0.0, 1.0, SQ2 ); IFSG_NORMALS* np = new IFSG_NORMALS( *face ); np->SetNormalList( 4, norm ); // create an appearance; appearances are owned by shapes // 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 ); // Shape2 shape->NewNode( *tx1 ); face->NewNode( *shape ); face->AddRefNode( *cp ); face->AddRefNode( *np ); coordIdx->NewNode( *face ); coordIdx->SetIndices( 3, &cidx[3] ); // red material->NewNode( *shape ); material->SetSpecular( 1.0, 0.0, 0.0 ); material->SetDiffuse( 0.9, 0.0, 0.0 ); material->SetAmbient( 0.9 ); material->SetShininess( 0.3 ); // Shape3 shape->NewNode( *tx1 ); face->NewNode( *shape ); face->AddRefNode( *cp ); face->AddRefNode( *np ); coordIdx->NewNode( *face ); coordIdx->SetIndices( 3, &cidx[6] ); // green material->NewNode( *shape ); material->SetSpecular( 0.0, 1.0, 0.0 ); material->SetDiffuse( 0.0, 0.9, 0.0 ); material->SetAmbient( 0.9 ); material->SetShininess( 0.3 ); // Shape4 shape->NewNode( *tx1 ); face->NewNode( *shape ); face->AddRefNode( *cp ); face->AddRefNode( *np ); coordIdx->NewNode( *face ); coordIdx->SetIndices( 3, &cidx[9] ); // blue material->NewNode( *shape ); material->SetSpecular( 0.0, 0.0, 1.0 ); material->SetDiffuse( 0.0, 0.0, 0.9 ); material->SetAmbient( 0.9 ); material->SetShininess( 0.3 ); // create a copy of the entire tetrahedron shifted Z+2 and rotated 2/3PI IFSG_TRANSFORM* tx2 = new IFSG_TRANSFORM( tx0->GetRawPtr() ); tx2->AddRefNode( *tx1 ); tx2->SetTranslation( SGPOINT( 0, 0, 2 ) ); tx2->SetRotation( SGVECTOR( 0, 0, 1 ), M_PI*2.0/3.0 ); SGNODE* data = tx0->GetRawPtr(); // delete the wrappers delete shape; delete face; delete coordIdx; delete material; delete cp; delete np; delete tx0; delete tx1; delete tx2; return (SCENEGRAPH*)data; } static S3D_PLUGIN_TETRA plugin_3d_tetra; #ifndef _WIN32 extern "C" __attribute__((__visibility__("default"))) S3D_PLUGIN* Get3DPlugin( void ) { return &plugin_3d_tetra; } #else extern "C" __declspec( dllexport ) S3D_PLUGIN* Get3DPlugin( void ) { return &plugin_3d_tetra; } #endif