Commit 02c8d4db authored by jean-pierre charras's avatar jean-pierre charras

Minor fixes: coding style in 3d-viewer and minor code cleanup, and some fixes...

Minor fixes: coding style in 3d-viewer and minor code cleanup, and some fixes in bom python scripts, which did not work when a non ascii char (but a valid utf8 symbol) was found in xml netlist. Add comments.
parent 435ca8a7
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2012 Jean-Pierre Charras, jp.charras@wanadoo.fr
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras@wanadoo.fr
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -43,18 +43,12 @@ S3D_MODEL_PARSER* S3D_MODEL_PARSER::Create( S3D_MASTER* aMaster,
const wxString aExtension )
{
if ( aExtension == wxT( "x3d" ) )
{
return new X3D_MODEL_PARSER( aMaster );
}
else if ( aExtension == wxT( "wrl" ) )
{
return new VRML_MODEL_PARSER( aMaster );
}
else
{
return NULL;
}
}
return NULL;
}
const wxString S3D_MASTER::GetShape3DFullFilename()
{
......
......@@ -246,12 +246,27 @@ private:
class VRML_MODEL_PARSER: public S3D_MODEL_PARSER
{
public:
/**
* ctor: initialize a VRML file parser
* @param aMaster = a ref to a 3D footprint shape description to fill
* by the vrml file data
*/
VRML_MODEL_PARSER( S3D_MASTER* aMaster );
~VRML_MODEL_PARSER();
/**
* Function load
* Load a 3D file and build a S3D_MASTER shape.
* file has .vrml ext and can be VRML 1 or VRML 2 format
* @param aFilename = the full filename to read
* @param aVrmlunits_to_3Dunits = the csaling factor to convert the 3D file unit
* to our internal units.
*/
void Load( const wxString& aFilename, double aVrmlunits_to_3Dunits );
private:
S3D_MASTER* m_curr3DShape; ///< the current 3D shape to build from the file
VRML1_MODEL_PARSER* vrml1_parser;
VRML2_MODEL_PARSER* vrml2_parser;
};
......
......@@ -36,6 +36,8 @@
#include "modelparsers.h"
#include "vrml_aux.h"
#define BUFLINE_SIZE 512
VRML1_MODEL_PARSER::VRML1_MODEL_PARSER( S3D_MASTER* aMaster ) :
S3D_MODEL_PARSER( aMaster )
{
......@@ -50,23 +52,19 @@ VRML1_MODEL_PARSER::VRML1_MODEL_PARSER( S3D_MASTER* aMaster ) :
VRML1_MODEL_PARSER::~VRML1_MODEL_PARSER()
{
for( unsigned int idx = 0; idx < childs.size(); idx++ )
{
delete childs[idx];
}
}
void VRML1_MODEL_PARSER::Load( const wxString& aFilename, double aVrmlunits_to_3Dunits )
{
char text[128];
char text[BUFLINE_SIZE];
// DBG( printf( "Load %s\n", GetChars(aFilename) ) );
m_file = wxFopen( aFilename, wxT( "rt" ) );
if( m_file == NULL )
{
return;
}
float vrmlunits_to_3Dunits = aVrmlunits_to_3Dunits;
glScalef( vrmlunits_to_3Dunits, vrmlunits_to_3Dunits, vrmlunits_to_3Dunits );
......@@ -122,7 +120,7 @@ void VRML1_MODEL_PARSER::Load( const wxString& aFilename, double aVrmlunits_to_3
int VRML1_MODEL_PARSER::read_separator()
{
char text[128];
char text[BUFLINE_SIZE];
// DBG( printf( "Separator\n" ) );
......@@ -161,9 +159,7 @@ int VRML1_MODEL_PARSER::read_separator()
read_NotImplemented( m_file, '}' );
}
else
{
break;
}
}
return 0;
......@@ -172,7 +168,7 @@ int VRML1_MODEL_PARSER::read_separator()
int VRML1_MODEL_PARSER::readMaterial()
{
char text[128];
char text[BUFLINE_SIZE];
S3D_MATERIAL* material = NULL;
// DBG( printf( " readMaterial\n" ) );
......@@ -229,7 +225,7 @@ int VRML1_MODEL_PARSER::readMaterial()
int VRML1_MODEL_PARSER::readCoordinate3()
{
char text[128];
char text[BUFLINE_SIZE];
// DBG( printf( " readCoordinate3\n" ) );
......@@ -257,7 +253,7 @@ int VRML1_MODEL_PARSER::readCoordinate3()
int VRML1_MODEL_PARSER::readIndexedFaceSet()
{
char text[128];
char text[BUFLINE_SIZE];
// DBG( printf( " readIndexedFaceSet\n" ) );
......
......@@ -39,6 +39,7 @@
#include "modelparsers.h"
#include "vrml_aux.h"
#define BUFLINE_SIZE 512
/**
* Trace mask used to enable or disable the trace output of the VRML V2 parser code.
......@@ -71,7 +72,7 @@ VRML2_MODEL_PARSER::~VRML2_MODEL_PARSER()
void VRML2_MODEL_PARSER::Load( const wxString& aFilename, double aVrmlunits_to_3Dunits )
{
char text[128];
char text[BUFLINE_SIZE];
wxLogTrace( traceVrmlV2Parser, wxT( "Load %s" ), GetChars( aFilename ) );
m_file = wxFopen( aFilename, wxT( "rt" ) );
......@@ -140,7 +141,7 @@ void VRML2_MODEL_PARSER::Load( const wxString& aFilename, double aVrmlunits_to_3
int VRML2_MODEL_PARSER::read_Transform()
{
char text[128];
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
......@@ -255,7 +256,7 @@ int VRML2_MODEL_PARSER::read_Transform()
int VRML2_MODEL_PARSER::read_DEF_Coordinate()
{
char text[128];
char text[BUFLINE_SIZE];
// Get the name of the definition.
if( !GetNextTag( m_file, text, sizeof(text) ) )
......@@ -288,7 +289,7 @@ int VRML2_MODEL_PARSER::read_DEF_Coordinate()
int VRML2_MODEL_PARSER::read_DEF()
{
char text[128];
char text[BUFLINE_SIZE];
if( !GetNextTag( m_file, text, sizeof(text) ) )
return -1;
......@@ -345,7 +346,7 @@ int VRML2_MODEL_PARSER::read_DEF()
int VRML2_MODEL_PARSER::read_USE()
{
char text[128];
char text[BUFLINE_SIZE];
// Get the name of the definition.
if( !GetNextTag( m_file, text, sizeof(text) ) )
......@@ -372,7 +373,7 @@ int VRML2_MODEL_PARSER::read_USE()
int VRML2_MODEL_PARSER::read_Shape()
{
char text[128];
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
......@@ -422,7 +423,7 @@ int VRML2_MODEL_PARSER::read_Shape()
int VRML2_MODEL_PARSER::read_Appearance()
{
char text[128];
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
......@@ -450,7 +451,7 @@ int VRML2_MODEL_PARSER::read_Appearance()
int VRML2_MODEL_PARSER::read_material()
{
S3D_MATERIAL* material = NULL;
char text[128];
char text[BUFLINE_SIZE];
if( GetNextTag( m_file, text, sizeof(text) ) )
{
......@@ -514,7 +515,7 @@ int VRML2_MODEL_PARSER::read_material()
int VRML2_MODEL_PARSER::read_Material()
{
char text[128];
char text[BUFLINE_SIZE];
glm::vec3 vertex;
while( GetNextTag( m_file, text, sizeof(text) ) )
......@@ -594,7 +595,7 @@ int VRML2_MODEL_PARSER::read_Material()
int VRML2_MODEL_PARSER::read_IndexedFaceSet()
{
char text[128];
char text[BUFLINE_SIZE];
m_normalPerVertex = false;
colorPerVertex = false;
......@@ -671,7 +672,7 @@ int VRML2_MODEL_PARSER::read_IndexedFaceSet()
int VRML2_MODEL_PARSER::read_IndexedLineSet()
{
char text[128];
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
......@@ -787,7 +788,7 @@ int VRML2_MODEL_PARSER::read_coordIndex()
int VRML2_MODEL_PARSER::read_Color()
{
char text[128];
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
......@@ -814,7 +815,7 @@ int VRML2_MODEL_PARSER::read_Color()
int VRML2_MODEL_PARSER::read_Normal()
{
char text[128];
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
......@@ -847,7 +848,7 @@ int VRML2_MODEL_PARSER::read_Normal()
int VRML2_MODEL_PARSER::read_Coordinate()
{
char text[128];
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
......@@ -876,7 +877,7 @@ int VRML2_MODEL_PARSER::read_Coordinate()
*/
int VRML2_MODEL_PARSER::read_CoordinateDef()
{
char text[128];
char text[BUFLINE_SIZE];
while( GetNextTag( m_file, text, sizeof(text) ) )
{
......
......@@ -41,21 +41,14 @@
VRML_MODEL_PARSER::VRML_MODEL_PARSER( S3D_MASTER* aMaster ) :
S3D_MODEL_PARSER( aMaster )
{
vrml1_parser = new VRML1_MODEL_PARSER( aMaster );
vrml2_parser = new VRML2_MODEL_PARSER( aMaster );
m_curr3DShape = aMaster;
vrml1_parser = NULL;
vrml2_parser = NULL;
}
VRML_MODEL_PARSER::~VRML_MODEL_PARSER()
{
if( vrml1_parser )
{
delete vrml1_parser;
}
if( vrml2_parser )
{
delete vrml2_parser;
}
}
......@@ -69,32 +62,32 @@ void VRML_MODEL_PARSER::Load( const wxString& aFilename, double aVrmlunits_to_3D
file = wxFopen( aFilename, wxT( "rt" ) );
if( file == NULL )
{
return;
}
if( fgets( line, 11, file ) == NULL )
{
fclose( file );
return;
}
fclose( file );
if( stricmp( line, "#VRML V2.0" ) == 0 )
{
//DBG( printf( "About to parser a #VRML V2.0 file\n" ) );
vrml2_parser = new VRML2_MODEL_PARSER( m_curr3DShape );
vrml2_parser->Load( aFilename, aVrmlunits_to_3Dunits );
delete vrml2_parser;
vrml2_parser = NULL;
return;
}
else if( stricmp( line, "#VRML V1.0" ) == 0 )
{
//DBG( printf( "About to parser a #VRML V1.0 file\n" ) );
vrml1_parser = new VRML1_MODEL_PARSER( m_curr3DShape );
vrml1_parser->Load( aFilename, aVrmlunits_to_3Dunits );
delete vrml1_parser;
vrml1_parser = NULL;
return;
}
......
......@@ -3,6 +3,13 @@
#
# Example: Sorted and Grouped CSV BOM
#
"""
@package
Generate a csv BOM list.
Components are sorted by ref and grouped by value
Fields are (if exist)
Item, Qty, Reference(s), Value, LibPart, Footprint, Datasheet
"""
from __future__ import print_function
......@@ -11,6 +18,29 @@ import kicad_netlist_reader
import csv
import sys
def myEqu(self, other):
"""myEqu is a more advanced equivalence function for components which is
used by component grouping. Normal operation is to group components based
on their value and footprint.
In this example of a custom equivalency operator we compare the
value, the part name and the footprint.
"""
result = True
if self.getValue() != other.getValue():
result = False
elif self.getPartName() != other.getPartName():
result = False
elif self.getFootprint() != other.getFootprint():
result = False
return result
# Override the component equivalence operator - it is important to do this
# before loading the netlist, otherwise all components will have the original
# equivalency operator.
kicad_netlist_reader.comp.__eq__ = myEqu
if len(sys.argv) != 3:
print("Usage ", __file__, "<generic_netlist.xml> <output.csv>", file=sys.stderr)
......@@ -48,17 +78,18 @@ columns = ['Item', 'Qty', 'Reference(s)', 'Value', 'LibPart', 'Footprint', 'Data
# Create a new csv writer object to use as the output formatter
out = csv.writer( f, lineterminator='\n', delimiter=',', quotechar='\"', quoting=csv.QUOTE_MINIMAL )
# override csv.writer's writerow() to support utf8 encoding:
# override csv.writer's writerow() to support encoding conversion (initial encoding is utf8):
def writerow( acsvwriter, columns ):
utf8row = []
for col in columns:
utf8row.append( str(col).encode('utf8') )
utf8row.append( str(col) ) # currently, no change
acsvwriter.writerow( utf8row )
# Output a set of rows as a header providing general information
writerow( out, ['Source:', net.getSource()] )
writerow( out, ['Date:', net.getDate()] )
writerow( out, ['Tool:', net.getTool()] )
writerow( out, ['Generator:', sys.argv[0]] )
writerow( out, ['Component Count:', len(components)] )
writerow( out, [] )
writerow( out, ['Individual Components:'] )
......@@ -129,6 +160,6 @@ for group in grouped:
for field in columns[7:]:
row.append( net.getGroupField(group, field) );
writerow( out, row )
writerow( out, row )
f.close()
......@@ -7,9 +7,9 @@
"""
@package
Generate a Tab delimited list (csv file type).
Components are sorted by ref and grouped by value
Components are sorted by ref and grouped by value with same footprint
Fields are (if exist)
'Ref', 'Qnty', 'Value', 'Sch lib name', 'footprint', 'Description', 'Vendor'
'Ref', 'Qnty', 'Value', 'Cmp name', 'Footprint', 'Description', 'Vendor'
"""
# Import the KiCad python helper module and the csv formatter
......@@ -37,8 +37,9 @@ out = csv.writer(f, lineterminator='\n', delimiter=',', quotechar='\"', quoting=
out.writerow(['Source:', net.getSource()])
out.writerow(['Date:', net.getDate()])
out.writerow(['Tool:', net.getTool()])
out.writerow( ['Generator:', sys.argv[0]] )
out.writerow(['Component Count:', len(net.components)])
out.writerow(['Ref', 'Qnty', 'Value', 'Sch lib name', 'footprint', 'Description', 'Vendor'])
out.writerow(['Ref', 'Qnty', 'Value', 'Cmp name', 'Footprint', 'Description', 'Vendor'])
# Get all of the components in groups of matching parts + values
# (see ky_generic_netlist_reader.py)
......@@ -55,7 +56,7 @@ for group in grouped:
c = component
# Fill in the component groups common data
out.writerow([refs, len(group), c.getValue(), c.getLibName() + "/" + c.getPartName(), c.getFootprint(),
out.writerow([refs, len(group), c.getValue(), c.getPartName(), c.getFootprint(),
c.getDescription(), c.getField("Vendor")])
......@@ -9,7 +9,7 @@
Generate a HTML BOM list.
Components are sorted and grouped by value
Fields are (if exist)
Ref, Quantity, Value, Part, Datasheet, Description, Vendor
Ref, Quantity, Value, Part, Footprint, Description, Vendor
"""
......@@ -43,7 +43,7 @@ html = """
def myEqu(self, other):
"""myEqu is a more advanced equivalence function for components which is
used by component grouping. Normal operation is to group components based
on their Value, Library source, and Library part.
on their Value and Footprint.
In this example of a more advanced equivalency operator we also compare the
custom fields Voltage, Tolerance and Manufacturer as well as the assigned
......@@ -54,8 +54,6 @@ def myEqu(self, other):
result = True
if self.getValue() != other.getValue():
result = False
elif self.getLibName() != other.getLibName():
result = False
elif self.getPartName() != other.getPartName():
result = False
elif self.getFootprint() != other.getFootprint():
......@@ -72,7 +70,7 @@ def myEqu(self, other):
# Override the component equivalence operator - it is important to do this
# before loading the netlist, otherwise all components will have the original
# equivalency operator.
kicad_netlist_reader.comp.__equ__ = myEqu
kicad_netlist_reader.comp.__eq__ = myEqu
# Generate an instance of a generic netlist, and load the netlist tree from
# <file>.tmp. If the file doesn't exist, execution will stop
......@@ -95,7 +93,7 @@ html = html.replace('<!--COMPCOUNT-->', "<b>Component Count:</b>" + \
str(len(net.components)))
row = "<tr><th style='width:640px'>Ref</th>" + "<th>Qnty</th>"
row += "<th>Value</th>" + "<th>Part</th>" + "<th>Datasheet</th>"
row += "<th>Value</th>" + "<th>Part</th>" + "<th>Footprint</th>"
row += "<th>Description</th>" + "<th>Vendor</th></tr>"
html = html.replace('<!--TABLEROW-->', row + "<!--TABLEROW-->")
......@@ -121,7 +119,7 @@ for group in grouped:
row = "\n "
row += "<tr><td>" + refs +"</td><td>" + str(len(group))
row += "</td><td>" + c.getValue() + "</td><td>" + c.getLibName() + ":"
row += c.getPartName() + "</td><td>" + c.getDatasheet() + "</td><td>"
row += c.getPartName() + "</td><td>" + c.getFootprint() + "</td><td>"
row += c.getDescription() + "</td><td>" + c.getField("Vendor")
row += "</td></tr>"
......
......@@ -2,6 +2,8 @@
# KiCad python module for interpreting generic netlists which can be used
# to generate Bills of materials, etc.
#
# Remember these files use UTF8 encoding
#
# No string formatting is used on purpose as the only string formatting that
# is current compatible with python 2.4+ to 3.0+ is the '%' method, and that
# is due to be deprecated in 3.0+ soon
......@@ -304,12 +306,24 @@ class comp():
self.grouped = False
def __eq__(self, other):
"""Equlivalency operator, remember this can be easily overloaded"""
""" Equivalency operator, remember this can be easily overloaded
2 components are equivalent ( i.e. can be grouped
if they have same value and same footprint
Override the component equivalence operator must be done before
loading the netlist, otherwise all components will have the original
equivalency operator.
You have to define a comparison module (for instance named myEqu)
and add the line;
kicad_netlist_reader.comp.__eq__ = myEqu
in your bom generator script before calling the netliste reader by something like:
net = kicad_netlist_reader.netlist(sys.argv[1])
"""
result = False
if self.getValue() == other.getValue():
if self.getLibName() == other.getLibName():
if self.getPartName() == other.getPartName():
result = True
if self.getFootprint() == other.getFootprint():
result = True
return result
def setLibPart(self, part):
......@@ -331,7 +345,7 @@ class comp():
v.setChars(value)
def getValue(self):
return self.element.get("value")
return self.element.get("value").encode( "utf-8" )
def getField(self, name, libraryToo=True):
"""Return the value of a field named name. The component is first
......@@ -347,7 +361,7 @@ class comp():
field = self.element.get("field", "name", name)
if field == "" and libraryToo:
field = self.libpart.getField(name)
field = self.libpart.getField(name).encode( "utf-8" )
return field
def getFieldNames(self):
......@@ -360,7 +374,7 @@ class comp():
fields = self.element.getChild('fields')
if fields:
for f in fields.getChildren():
fieldNames.append( f.get('field','name') )
fieldNames.append( f.get('field','name').encode( "utf-8" ) )
return fieldNames
def getRef(self):
......@@ -382,7 +396,7 @@ class comp():
return self.element.get("tstamp")
def getDescription(self):
return self.libpart.getDescription()
return self.libpart.getDescription().encode( "utf-8" )
class netlist():
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment