mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Try to better my life as a programmer, starting with more comments and documentation
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,71 @@
|
||||
###############################################################################
|
||||
# #
|
||||
# This file is part of IfcOpenShell. #
|
||||
# #
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify #
|
||||
# it under the terms of the Lesser GNU General Public License as published by #
|
||||
# the Free Software Foundation, either version 3.0 of the License, or #
|
||||
# (at your option) any later version. #
|
||||
# #
|
||||
# IfcOpenShell 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 #
|
||||
# Lesser GNU General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the Lesser GNU General Public License #
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
###############################################################################
|
||||
# #
|
||||
# This files uses the documentation files from buildingSMART to generate #
|
||||
# descriptions from EXPRESS names that are suitable for comments in the C++ #
|
||||
# code. The .csv files used by this file are generated from the MS Office #
|
||||
# Access database, which in turn has been generated from the IFC baseline #
|
||||
# documentation by the IFCDOC utility provided by buildingSMART. #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
import re,csv
|
||||
import csv
|
||||
try: from html.entities import entitydefs
|
||||
except: from htmlentitydefs import entitydefs
|
||||
|
||||
name_to_oid = {}
|
||||
oid_to_desc = {}
|
||||
oid_to_name = {}
|
||||
oid_to_pid = {}
|
||||
regices = list(zip([re.compile(s,re.M) for s in [r'<[\w\n=" \-/\.;_\t:%#,\?\(\)]+>',r'(\n[\t ]*){2,}',r'^[\t ]+','^']],['','\n\n',' ','/// ']))
|
||||
|
||||
definition_files = ['DocEntity.csv', 'DocEnumeration.csv', 'DocDefined.csv', 'DocSelect.csv']
|
||||
for fn in definition_files:
|
||||
with open(fn) as f:
|
||||
for oid, name, desc in csv.reader(f, delimiter=';', quotechar='"'):
|
||||
name_to_oid[name] = oid
|
||||
oid_to_name[oid] = name
|
||||
oid_to_desc[oid] = desc
|
||||
|
||||
with open('DocEntityAttributes.csv') as f:
|
||||
for pid, x, oid in csv.reader(f, delimiter=';', quotechar='"'):
|
||||
oid_to_pid[oid] = pid
|
||||
|
||||
with open('DocAttribute.csv') as f:
|
||||
for oid, name, desc in csv.reader(f, delimiter=';', quotechar='"'):
|
||||
pid = oid_to_pid[oid]
|
||||
pname = oid_to_name[pid]
|
||||
name_to_oid[(pname, name)] = oid
|
||||
oid_to_desc[oid] = desc
|
||||
|
||||
def description(item):
|
||||
global name_to_oid, oid_to_desc, oid_to_name, oid_to_pid
|
||||
oid = name_to_oid.get(item,0)
|
||||
desc = oid_to_desc.get(oid,None)
|
||||
if desc:
|
||||
for a,b in entitydefs.items(): desc = desc.replace("&%s;"%a,b)
|
||||
desc = desc.replace("\r","")
|
||||
for r,s in regices[:-1]: desc = r.sub(s,desc)
|
||||
desc = desc.strip()
|
||||
r,s = regices[-1]
|
||||
desc = r.sub(s,desc)
|
||||
return desc
|
||||
@@ -34,6 +34,8 @@ header = """
|
||||
###############################################################################
|
||||
|
||||
import os, sys
|
||||
import IfcDocumentation
|
||||
|
||||
filename = sys.argv[1]
|
||||
|
||||
#
|
||||
@@ -160,12 +162,14 @@ class Typedef:
|
||||
self.len = len(self.type)
|
||||
elif isinstance(self.type,SelectType): selections.add(self.name)
|
||||
simple_types.add(self.name)
|
||||
comment = IfcDocumentation.description(self.name)
|
||||
self.comment = comment+"\n" if comment else ''
|
||||
def __str__(self):
|
||||
global generator_mode
|
||||
if generator_mode == 'HEADER' and isinstance(self.type,EnumType):
|
||||
return ("namespace %(name)s {typedef %(type)s %(name)s;\nstd::string ToString(%(name)s v);\n%(name)s FromString(const std::string& s);}"%self.__dict__)%self.__dict__
|
||||
return ("namespace %(name)s {\n%(comment)stypedef %(type)s %(name)s;\nstd::string ToString(%(name)s v);\n%(name)s FromString(const std::string& s);\n}"%self.__dict__)%self.__dict__
|
||||
elif generator_mode == 'HEADER':
|
||||
return "typedef %s %s;"%(self.type,self.name)
|
||||
return "%stypedef %s %s;"%(self.comment,self.type,self.name)
|
||||
elif generator_mode == 'SOURCE' and isinstance(self.type,EnumType):
|
||||
generator_mode = 'SOURCE_TO'
|
||||
s = "std::string %(name)s::ToString(%(name)s v) {\n if ( v < 0 || v >= %(len)d ) throw IfcException(\"Unable to find find keyword in schema\");\n const char* names[] = %(type)s;\n return names[v];\n}\n"%self.__dict__
|
||||
@@ -185,7 +189,7 @@ class ArgumentList:
|
||||
s = ""
|
||||
argv = self.argstart
|
||||
for a in self.l:
|
||||
class_name = indent = ""
|
||||
class_name = indent = comment = optional_comment = ""
|
||||
return_type = str(a.type)
|
||||
if generator_mode == 'SOURCE':
|
||||
class_name = "%(class_name)s::"
|
||||
@@ -204,13 +208,17 @@ class ArgumentList:
|
||||
function_body2 = " { return !entity->getArgument(%d)->isNull(); }"%argv
|
||||
else:
|
||||
indent = " "
|
||||
function_body = function_body2 = ";"
|
||||
if a.optional: s += "\n%sbool %shas%s()%s"%(indent,class_name,a.name,function_body2)
|
||||
function_body = function_body2 = ";"
|
||||
comment = IfcDocumentation.description((self.class_name,a.name))
|
||||
comment = comment+"\n" if comment else ''
|
||||
comment = comment.replace("///","%s///"%indent)
|
||||
optional_comment = "%s/// Whether the optional attribute %s is defined for this %s\n"%(indent,a.name,self.class_name)
|
||||
if a.optional: s += "\n%s%sbool %shas%s()%s"%(optional_comment,indent,class_name,a.name,function_body2)
|
||||
if ( str(a.type) in enumerations ):
|
||||
return_type = "%(type)s::%(type)s"%a.__dict__
|
||||
elif ( str(a.type) in entity_names ):
|
||||
return_type = "%(type)s*"%a.__dict__
|
||||
s += "\n%s%s %s%s()%s"%(indent,return_type,class_name,a.name,function_body)
|
||||
s += "\n%s%s%s %s%s()%s"%(comment,indent,return_type,class_name,a.name,function_body)
|
||||
argv += 1
|
||||
return s
|
||||
class InverseList:
|
||||
@@ -228,12 +236,15 @@ class InverseList:
|
||||
class Classdef:
|
||||
def __init__(self,l):
|
||||
self.class_name, self.parent_class, self.arguments, self.inverse = l
|
||||
self.arguments.class_name = self.class_name
|
||||
entity_names.add(self.class_name)
|
||||
parent_relations[self.class_name] = self.parent_class
|
||||
argument_count[self.class_name] = len(self.arguments)
|
||||
def __str__(self):
|
||||
if generator_mode == 'HEADER':
|
||||
return "class %s : public %s {\npublic:%s%s%s\n};" % (self.class_name,
|
||||
comment = IfcDocumentation.description(self.class_name)
|
||||
comment = comment+"\n" if comment else ''
|
||||
return "%sclass %s : public %s {\npublic:%s%s%s\n};" % (comment,self.class_name,
|
||||
"IfcBaseClass" if self.parent_class is None else self.parent_class,
|
||||
self.arguments,
|
||||
self.inverse,
|
||||
@@ -247,7 +258,7 @@ class Classdef:
|
||||
)
|
||||
elif generator_mode == 'SOURCE':
|
||||
self.arguments.argstart = argument_start(self.class_name)
|
||||
return (("\n// %(class_name)s"+str(self.arguments)+str(self.inverse)+
|
||||
return (("\n// Function implementations for %(class_name)s"+str(self.arguments)+str(self.inverse)+
|
||||
("\nbool %(class_name)s::is(Type::Enum v) const { return v == Type::%(class_name)s; }" if self.parent_class is None else
|
||||
"\nbool %(class_name)s::is(Type::Enum v) const { return v == Type::%(class_name)s || %(parent_class)s::is(v); }")+
|
||||
"\nType::Enum %(class_name)s::type() const { return Type::%(class_name)s; }"+
|
||||
|
||||
+653
-653
File diff suppressed because it is too large
Load Diff
+27376
-328
File diff suppressed because one or more lines are too long
+13
-2
@@ -33,7 +33,13 @@
|
||||
const int BUF_SIZE = (128 * 1024 * 1024);
|
||||
|
||||
namespace IfcParse {
|
||||
|
||||
/// The File class represents a ISO 10303-21 IFC-SPF file in memory.
|
||||
/// The file is interpreted as a sequence of tokens which are lazily
|
||||
/// interpreted only when requested. If the size of the file is
|
||||
/// larger than BUF_SIZE, the file is split into seperate pages, of
|
||||
/// which only one is simultaneously kept in memory, for files
|
||||
/// that define their entities not in a sequential nature, this is
|
||||
/// detrimental for the performance of the parser.
|
||||
class File {
|
||||
private:
|
||||
std::ifstream stream;
|
||||
@@ -50,11 +56,16 @@ namespace IfcParse {
|
||||
File(const std::string& fn);
|
||||
File(std::istream& f, int len);
|
||||
File(void* data, int len);
|
||||
/// Returns the character at the cursor
|
||||
char Peek();
|
||||
/// Returns the character at specified offset
|
||||
char Read(unsigned int offset);
|
||||
void Inc();
|
||||
/// Increment the file cursor and reads new page if necessary
|
||||
void Inc();
|
||||
void Close();
|
||||
/// Moves the file cursor to an arbitrary offset in the file
|
||||
void Seek(unsigned int offset);
|
||||
/// Returns the cursor position
|
||||
unsigned int Tell();
|
||||
};
|
||||
}
|
||||
|
||||
+43
-30
@@ -52,24 +52,33 @@ namespace IfcParse {
|
||||
|
||||
typedef unsigned int Token;
|
||||
|
||||
//
|
||||
// Provides functions to convert Tokens to binary data
|
||||
// Tokens are merely offsets to where they can be read in the file
|
||||
//
|
||||
/// Provides functions to convert Tokens to binary data
|
||||
/// Tokens are merely offsets to where they can be read in the file
|
||||
class TokenFunc {
|
||||
private:
|
||||
static bool startsWith(Token t, char c);
|
||||
public:
|
||||
/// Returns the offset at which the token is read from the file
|
||||
static unsigned int Offset(Token t);
|
||||
/// Returns whether the token can be interpreted as a string
|
||||
static bool isString(Token t);
|
||||
/// Returns whether the token can be interpreted as an identifier
|
||||
static bool isIdentifier(Token t);
|
||||
/// Returns whether the token can be interpreted as an syntactical operator
|
||||
static bool isOperator(Token t, char op = 0);
|
||||
/// Returns whether the token can be interpreted as an enumerated value
|
||||
static bool isEnumeration(Token t);
|
||||
/// Returns whether the token can be interpreted as an datatype name
|
||||
static bool isDatatype(Token t);
|
||||
/// Returns the token interpreted as an integer
|
||||
static int asInt(Token t);
|
||||
/// Returns the token interpreted as an boolean (.T. or .F.)
|
||||
static bool asBool(Token t);
|
||||
/// Returns the token as a floating point number
|
||||
static double asFloat(Token t);
|
||||
/// Returns the token as a string (without the dot or apostrophe)
|
||||
static std::string asString(Token t);
|
||||
/// Returns a string representation of the token (including the dot or apostrophe)
|
||||
static std::string toString(Token t);
|
||||
};
|
||||
|
||||
@@ -81,9 +90,7 @@ namespace IfcParse {
|
||||
Token TokenPtr(char c);
|
||||
Token TokenPtr();
|
||||
|
||||
//
|
||||
// Interprets a file as a sequential stream of Tokens
|
||||
//
|
||||
/// A stream of tokens to be read from a File.
|
||||
class Tokens {
|
||||
private:
|
||||
File* file;
|
||||
@@ -95,11 +102,9 @@ namespace IfcParse {
|
||||
std::string TokenString(unsigned int offset);
|
||||
};
|
||||
|
||||
//
|
||||
// Argument of type list, e.g.
|
||||
// #1=IfcDirection((1.,0.,0.));
|
||||
// ==========
|
||||
//
|
||||
/// Argument of type list, e.g.
|
||||
/// #1=IfcDirection((1.,0.,0.));
|
||||
/// ==========
|
||||
class ArgumentList: public Argument {
|
||||
private:
|
||||
std::vector<ArgumentPtr> list;
|
||||
@@ -123,11 +128,9 @@ namespace IfcParse {
|
||||
bool isNull() const;
|
||||
};
|
||||
|
||||
//
|
||||
// Argument of type scalar or string, e.g.
|
||||
// #1=IfcVector(#2,1.0);
|
||||
// == ===
|
||||
//
|
||||
/// Argument of type scalar or string, e.g.
|
||||
/// #1=IfcVector(#2,1.0);
|
||||
/// == ===
|
||||
class TokenArgument : public Argument {
|
||||
private:
|
||||
|
||||
@@ -150,11 +153,9 @@ namespace IfcParse {
|
||||
bool isNull() const;
|
||||
};
|
||||
|
||||
//
|
||||
// Argument of an IFC type
|
||||
// #1=IfcTrimmedCurve(#2,(IFCPARAMETERVALUE(0.)),(IFCPARAMETERVALUE(1.)),.T.,.PARAMETER.);
|
||||
// ===================== =====================
|
||||
//
|
||||
/// Argument of an IFC simple type
|
||||
/// #1=IfcTrimmedCurve(#2,(IFCPARAMETERVALUE(0.)),(IFCPARAMETERVALUE(1.)),.T.,.PARAMETER.);
|
||||
/// ===================== =====================
|
||||
class EntityArgument : public Argument {
|
||||
private:
|
||||
IfcUtil::IfcArgumentSelect* entity;
|
||||
@@ -177,17 +178,17 @@ namespace IfcParse {
|
||||
bool isNull() const;
|
||||
};
|
||||
|
||||
//
|
||||
// Entity defined in an IFC file, e.g.
|
||||
// #1=IfcDirection((1.,0.,0.));
|
||||
// ============================
|
||||
//
|
||||
/// Entity defined in an IFC file, e.g.
|
||||
/// #1=IfcDirection((1.,0.,0.));
|
||||
/// ============================
|
||||
class Entity : public IfcAbstractEntity {
|
||||
private:
|
||||
ArgumentPtr args;
|
||||
Ifc2x3::Type::Enum _type;
|
||||
public:
|
||||
/// The EXPRESS ENTITY_NAME
|
||||
unsigned int _id;
|
||||
/// The offset at which the entity is read
|
||||
unsigned int offset;
|
||||
Entity(unsigned int i, Tokens* t);
|
||||
Entity(unsigned int i, Tokens* t, unsigned int o);
|
||||
@@ -213,9 +214,8 @@ typedef std::map<std::string,Ifc2x3::IfcRoot::ptr> MapEntityByGuid;
|
||||
typedef std::map<unsigned int,IfcEntities> MapEntitiesByRef;
|
||||
typedef std::map<unsigned int,unsigned int> MapOffsetById;
|
||||
|
||||
//
|
||||
// Several static convenience functions and variables
|
||||
//
|
||||
/// This class provides several static convenience functions and variables
|
||||
/// and provide access to the entities in an IFC file
|
||||
class Ifc {
|
||||
private:
|
||||
static MapEntityById byid;
|
||||
@@ -228,12 +228,19 @@ private:
|
||||
static std::ostream* log2;
|
||||
static std::stringstream log_stream;
|
||||
public:
|
||||
/// Returns the first entity in the file, this probably is the entity with the lowest id (EXPRESS ENTITY_NAME)
|
||||
static MapEntityById::const_iterator First();
|
||||
/// Returns the last entity in the file, this probably is the entity with the highes id (EXPRESS ENTITY_NAME)
|
||||
static MapEntityById::const_iterator Last();
|
||||
/// Determines to what stream respectively progress and errors are logged
|
||||
static void SetOutput(std::ostream* l1, std::ostream* l2);
|
||||
/// Log a message to the output stream
|
||||
static void LogMessage(const std::string& type, const std::string& message, const IfcAbstractEntityPtr entity=0);
|
||||
static IfcParse::File* file;
|
||||
static IfcParse::Tokens* tokens;
|
||||
/// Returns all entities in the file that match the template argument.
|
||||
/// NOTE: This also returns subtypes of the requested type, for example:
|
||||
/// IfcWall will also return IfcWallStandardCase entities
|
||||
template <class T>
|
||||
static typename T::list EntitiesByType() {
|
||||
IfcEntities e = EntitiesByType(T::Class());
|
||||
@@ -244,9 +251,15 @@ public:
|
||||
}
|
||||
return l;
|
||||
}
|
||||
/// Returns all entities in the file that match the positional argument.
|
||||
/// NOTE: This also returns subtypes of the requested type, for example:
|
||||
/// IfcWall will also return IfcWallStandardCase entities
|
||||
static IfcEntities EntitiesByType(Ifc2x3::Type::Enum t);
|
||||
/// Returns all entities in the file that reference the id
|
||||
static IfcEntities EntitiesByReference(int id);
|
||||
/// Returns the entity with the specified id
|
||||
static IfcEntity EntityById(int id);
|
||||
/// Returns the entity with the specified GlobalId
|
||||
static Ifc2x3::IfcRoot::ptr Ifc::EntityByGuid(const std::string& guid);
|
||||
static bool Init(const std::string& fn);
|
||||
static bool Init(std::istream& fn, int len);
|
||||
|
||||
Reference in New Issue
Block a user