mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
Merge branch 'master' into v0.6.0
# Conflicts: # src/ifcconvert/IfcConvert.cpp # src/ifcgeom/IfcGeomFilter.h # src/ifcgeom/IfcGeomIteratorImplementation.h # src/ifcgeom/IfcGeomWires.cpp # src/ifcparse/IfcFile.h # src/ifcparse/IfcLogger.cpp # src/ifcparse/IfcLogger.h # src/ifcparse/IfcParse.cpp # src/serializers/SvgSerializer.cpp # src/serializers/schema_dependent/XmlSerializer.cpp
This commit is contained in:
@@ -77,10 +77,12 @@ or Clang 3.5 has been confirmed to work.
|
||||
|
||||
### Compiling on *nix
|
||||
|
||||
The following instructions are for Ubuntu, modify as required for other operating systems. [nix/build-all.sh] script
|
||||
The following instructions are for Ubuntu, modify as required for other operating systems. [nix/build-all.py] script
|
||||
can be experimented with and studied for pointers for other operating systems, but note that this script is not currently
|
||||
meant to be used for a typical IfcOpenShell workspace setup.
|
||||
|
||||
Note: where `make -j` is written, add a number roughly equal to the amount of CPU cores + 1.
|
||||
|
||||
**1)** Install most of the prerequisites and dependencies:
|
||||
|
||||
$ sudo apt-get install git cmake gcc g++ libboost-all-dev libicu-dev
|
||||
@@ -103,7 +105,7 @@ meant to be used for a typical IfcOpenShell workspace setup.
|
||||
|
||||
**3)** For building IfcConvert with COLLADA (.dae) support (on by default), OpenCOLLADA is needed:
|
||||
|
||||
$ sudo apt-get install libpcre3-dev
|
||||
$ sudo apt-get install libpcre3-dev libxml2-dev
|
||||
$ git clone https://github.com/KhronosGroup/OpenCOLLADA.git
|
||||
$ cd OpenCOLLADA
|
||||
Using a known good revision, but HEAD should work too:
|
||||
@@ -135,6 +137,15 @@ If all worked out correctly you can now use IfcOpenShell. See the examples below
|
||||
|
||||
$ sudo make install
|
||||
|
||||
Installing IfcOpenShell with Conda
|
||||
----------------------------------
|
||||
Another option for building and installing IfcOpenShell is to use the popular
|
||||
[Anaconda Python Distribution](https://www.anaconda.com/download).
|
||||
The requirements are spread across a number of channels.
|
||||
You can add these channels to your configuration, or specify them all on the command line:
|
||||
|
||||
$ conda install -c conda-forge -c oce -c dlr-sc -c ifcopenshell ifcopenshell
|
||||
|
||||
Usage examples
|
||||
--------------
|
||||
|
||||
@@ -214,4 +225,4 @@ Usage examples
|
||||
[Visual C++ Build Tools]: http://landinghub.visualstudio.com/visual-cpp-build-tools "Visual C++ Build Tools"
|
||||
[MSYS2]: https://msys2.github.io/ "MSYS2"
|
||||
[win/readme.md]: https://github.com/IfcOpenShell/IfcOpenShell/tree/master/win/readme.md "win/readme.md"
|
||||
[nix/build-all.sh]: https://github.com/IfcOpenShell/IfcOpenShell/tree/master/nix/build-all.sh "nix/build-all.sh"
|
||||
[nix/build-all.py]: https://github.com/IfcOpenShell/IfcOpenShell/tree/master/nix/build-all.py "nix/build-all.py"
|
||||
|
||||
@@ -554,8 +554,9 @@ if(NOT MSVC)
|
||||
message(FATAL_ERROR "OCCT7 requires a compiler with C++11 support")
|
||||
endif()
|
||||
else()
|
||||
add_definitions(-std=c++03)
|
||||
add_definitions(-std=c++0x)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
set(IFCOPENSHELL_LIBRARIES IfcParse IfcGeom_ifc2x3 IfcGeom_ifc4 IfcGeom IfcGeom_ifc2x3 IfcGeom_ifc4 IfcGeom Serializers_ifc2x3 Serializers_ifc4 Serializers Serializers_ifc2x3 Serializers_ifc4 Serializers)
|
||||
|
||||
+29
-13
@@ -59,8 +59,10 @@ logger.addHandler(ch)
|
||||
|
||||
PROJECT_NAME="IfcOpenShell"
|
||||
OCE_VERSION="0.18"
|
||||
OCCT_VERSION="7.1.0"
|
||||
OCCT_HASH="89aebde"
|
||||
# OCCT_VERSION="7.1.0"
|
||||
# OCCT_HASH="89aebde"
|
||||
OCCT_VERSION="7.2.0"
|
||||
OCCT_HASH="88af392"
|
||||
PYTHON_VERSIONS=["2.7.12", "3.2.6", "3.3.6", "3.4.6", "3.5.3", "3.6.2"]
|
||||
BOOST_VERSION="1.59.0"
|
||||
PCRE_VERSION="8.39"
|
||||
@@ -183,7 +185,7 @@ cecho(""" - How many compiler processes may be run in parallel.
|
||||
|
||||
# Check that required tools are in PATH
|
||||
|
||||
for cmd in [git, bunzip2, tar, cc, cplusplus, autoconf, automake, yacc, make]:
|
||||
for cmd in [git, bunzip2, tar, cc, cplusplus, autoconf, automake, yacc, make, "patch"]:
|
||||
if which(cmd) is None:
|
||||
raise ValueError("Required tool '%s' not installed or not added to PATH" % (cmd,))
|
||||
|
||||
@@ -240,7 +242,7 @@ def __check_output__(cmds, cwd=None):
|
||||
|
||||
BOOST_VERSION_UNDERSCORE=BOOST_VERSION.replace(".", "_")
|
||||
ICU_VERSION_UNDERSCORE=ICU_VERSION.replace(".", "_")
|
||||
CMAKE_VERSION_2=CMAKE_VERSION[0:3]
|
||||
CMAKE_VERSION_2=CMAKE_VERSION[:CMAKE_VERSION.rindex('.')]
|
||||
|
||||
OCE_LOCATION="https://github.com/tpaviot/oce/archive/OCE-%s.tar.gz" % (OCE_VERSION,)
|
||||
BOOST_LOCATION="http://downloads.sourceforge.net/project/boost/boost/%s/boost_%s.tar.bz2" % (BOOST_VERSION, BOOST_VERSION_UNDERSCORE)
|
||||
@@ -284,7 +286,7 @@ def git_clone(clone_url, target_dir, revision=None):
|
||||
if revision != None:
|
||||
__check_call__([git, "checkout", revision], cwd=target_dir)
|
||||
|
||||
def build_dependency(name, mode, build_tool_args, download_url, download_name, download_tool=download_tool_default, revision=None, additional_files={}, no_append_name=False):
|
||||
def build_dependency(name, mode, build_tool_args, download_url, download_name, download_tool=download_tool_default, revision=None, patch=None, additional_files={}, no_append_name=False):
|
||||
"""Handles building of dependencies with different tools (which are
|
||||
distinguished with the `mode` argument. `build_tool_args` is expected to be
|
||||
a list which is necessary in order to not mess up quoting of compiler and
|
||||
@@ -347,6 +349,14 @@ def build_dependency(name, mode, build_tool_args, download_url, download_name, d
|
||||
if not os.path.exists(path):
|
||||
urllib.urlretrieve(url, os.path.join(extract_dir, path))
|
||||
|
||||
if patch is not None:
|
||||
patch_abs = os.path.abspath(os.path.join(os.path.dirname(__file__), patch))
|
||||
if os.path.exists(patch_abs):
|
||||
try: __check_call__(["patch", "-p1", "--batch", "--forward", "-i", patch_abs], cwd=extract_dir)
|
||||
except Exception as e:
|
||||
# Assert that the patch has already been applied
|
||||
__check_call__(["patch", "-p1", "--batch", "--reverse", "--dry-run", "-i", patch_abs], cwd=extract_dir)
|
||||
|
||||
if mode != "bjam":
|
||||
extract_build_dir = os.path.join(extract_dir, "build")
|
||||
if os.path.exists(extract_build_dir):
|
||||
@@ -457,7 +467,15 @@ build_dependency(name="pcre-%s" % (PCRE_VERSION,), mode="autoconf", build_tool_a
|
||||
build_dependency(name="swig", mode="autoconf", build_tool_args=["--with-pcre-prefix=%s/install/pcre-%s" % (DEPS_DIR, PCRE_VERSION)], download_url="https://github.com/swig/swig.git", download_name="swig", download_tool=download_tool_git, revision="rel-%s" % SWIG_VERSION)
|
||||
|
||||
if USE_OCCT:
|
||||
long_filename = "src/RWStepVisual/RWStepVisual_RWCharacterizedObjectAndCharacterizedRepresentationAndDraughtingModelAndRepresentation"
|
||||
long_filenames = ["src/RWStepVisual/RWStepVisual_RWCharacterizedObjectAndCharacterizedRepresentationAndDraughtingModelAndRepresentation"]
|
||||
if OCCT_VERSION == "7.2.0":
|
||||
long_filenames += [
|
||||
"src/StepVisual/StepVisual_AnnotationCurveOccurrenceAndAnnotationOccurrenceAndGeomReprItemAndReprItemAndStyledItem",
|
||||
"src/RWStepVisual/RWStepVisual_RWAnnotationCurveOccurrenceAndAnnotationOccurrenceAndGeomReprItemAndReprItemAndStyledItem"
|
||||
]
|
||||
long_filenames_ext = [("%s.hxx" % fn) for fn in long_filenames] + [("%s.cxx" % fn) for fn in long_filenames]
|
||||
patch_filename = "patches/occt/%s.patch" % OCCT_HASH
|
||||
|
||||
occt_gitweb = "http://git.dev.opencascade.org/gitweb/?p=occt.git"
|
||||
build_dependency(
|
||||
name="occt-%s" % OCCT_VERSION,
|
||||
@@ -467,13 +485,11 @@ if USE_OCCT:
|
||||
"-DBUILD_LIBRARY_TYPE=Static",
|
||||
"-DBUILD_MODULE_Draw=0",
|
||||
],
|
||||
download_url="%s;a=snapshot;h=%s;sf=tgz" % (occt_gitweb, OCCT_HASH),
|
||||
additional_files = {
|
||||
"%s.hxx" % (long_filename): "%s;a=blob_plain;hb=%s;f=%s.hxx" % (occt_gitweb, OCCT_HASH, long_filename),
|
||||
"%s.cxx" % (long_filename): "%s;a=blob_plain;hb=%s;f=%s.cxx" % (occt_gitweb, OCCT_HASH, long_filename)
|
||||
},
|
||||
download_name="occt-%s.tar.gz" % OCCT_HASH,
|
||||
no_append_name=True)
|
||||
download_url = "%s;a=snapshot;h=%s;sf=tgz" % (occt_gitweb, OCCT_HASH),
|
||||
additional_files = {fn: "%s;a=blob_plain;hb=%s;f=%s" % (occt_gitweb, OCCT_HASH, fn) for fn in long_filenames_ext},
|
||||
patch = patch_filename,
|
||||
download_name = "occt-%s.tar.gz" % OCCT_HASH,
|
||||
no_append_name = True)
|
||||
else:
|
||||
build_dependency(name="oce-%s" % (OCE_VERSION,), mode="cmake", build_tool_args=["-DOCE_DISABLE_TKSERVICE_FONT=ON", "-DOCE_TESTING=OFF", "-DOCE_BUILD_SHARED_LIB=OFF", "-DOCE_DISABLE_X11=ON", "-DOCE_VISUALISATION=OFF", "-DOCE_OCAF=OFF", "-DOCE_INSTALL_PREFIX=%s/install/oce-%s" % (DEPS_DIR, OCE_VERSION)], download_url="https://github.com/tpaviot/oce/archive/", download_name="OCE-%s.tar.gz" % (OCE_VERSION,))
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff;h=0ab4e621833f4eae945a3762c9a29ee12e2eec53#patch1
|
||||
diff --git a/src/HLRBRep/HLRBRep_InternalAlgo.cxx b/src/HLRBRep/HLRBRep_InternalAlgo.cxx
|
||||
index ca885ca..c13cb06 100644 (file)
|
||||
--- a/src/HLRBRep/HLRBRep_InternalAlgo.cxx
|
||||
+++ b/src/HLRBRep/HLRBRep_InternalAlgo.cxx
|
||||
@@ -165,7 +165,7 @@ void HLRBRep_InternalAlgo::Update ()
|
||||
SB.Bounds(v1,v2,e1,e2,f1,f2);
|
||||
|
||||
for (Standard_Integer e = e1; e <= e2; e++) {
|
||||
- HLRBRep_EdgeData ed = aEDataArray.ChangeValue(e);
|
||||
+ HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(e);
|
||||
HLRAlgo::DecodeMinMax(ed.MinMax(), TheMin, TheMax);
|
||||
if (FirstTime) {
|
||||
FirstTime = Standard_False;
|
||||
@@ -307,7 +307,7 @@ void HLRBRep_InternalAlgo::InitEdgeStatus ()
|
||||
Standard_Integer nf = myDS->NbFaces();
|
||||
|
||||
for (Standard_Integer e = 1; e <= ne; e++) {
|
||||
- HLRBRep_EdgeData ed = aEDataArray.ChangeValue(e);
|
||||
+ HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(e);
|
||||
if (ed.Selected()) ed.Status().ShowAll();
|
||||
}
|
||||
// for (Standard_Integer f = 1; f <= nf; f++) {
|
||||
@@ -368,7 +368,7 @@ void HLRBRep_InternalAlgo::Select ()
|
||||
Standard_Integer nf = myDS->NbFaces();
|
||||
|
||||
for (Standard_Integer e = 1; e <= ne; e++) {
|
||||
- HLRBRep_EdgeData ed = aEDataArray.ChangeValue(e);
|
||||
+ HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(e);
|
||||
ed.Selected(Standard_True);
|
||||
}
|
||||
|
||||
@@ -92,7 +92,8 @@ def import_ifc(filename, use_names, process_relations, blender_booleans):
|
||||
faces = [[f[i], f[i + 1], f[i + 2]] \
|
||||
for i in range(0, len(f), 3)]
|
||||
|
||||
me = bpy.data.meshes.new('mesh%d' % ob.geometry.id)
|
||||
# Depending on version, geometry.id will be either int or str
|
||||
me = bpy.data.meshes.new('mesh-%r' % ob.geometry.id)
|
||||
me.from_pydata(verts, [], faces)
|
||||
me.validate()
|
||||
|
||||
|
||||
+108
-62
@@ -113,7 +113,7 @@ bool rename_file(const std::string& old_filename, const std::string& new_filenam
|
||||
}
|
||||
|
||||
static std::stringstream log_stream;
|
||||
void write_log();
|
||||
void write_log(bool);
|
||||
|
||||
/// @todo make the filters non-global
|
||||
/*
|
||||
@@ -154,13 +154,16 @@ bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file,
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
std::string log_format;
|
||||
po::options_description generic_options("Command line options");
|
||||
generic_options.add_options()
|
||||
("help,h", "display usage information")
|
||||
("version", "display version information")
|
||||
("verbose,v", "more verbose output")
|
||||
("yes,y", "answer 'yes' automatically to possible confirmation queries (e.g. overwriting an existing output file)")
|
||||
("no-progress", "Suppress possible progress bar type of prints that use carriage return.");
|
||||
("verbose,v", "more verbose log messages")
|
||||
("quiet,q", "less status and progress output")
|
||||
("yes,y", "answer 'yes' automatically to possible confirmation queries (e.g. overwriting an existing output file)")
|
||||
("no-progress", "suppress possible progress bar type of prints that use carriage return")
|
||||
("log-format", po::value<std::string>(&log_format), "log format: plain or json");
|
||||
|
||||
po::options_description fileio_options;
|
||||
fileio_options.add_options()
|
||||
@@ -305,6 +308,8 @@ int main(int argc, char** argv)
|
||||
("site-local-placement",
|
||||
"Place elements locally in the IfcSite coordinate system, instead of placing "
|
||||
"them in the IFC global coords. Applicable for OBJ and DAE output.")
|
||||
("building-local-placement",
|
||||
"Similar to --site-local-placement, but placing elements in locally in the parent IfcBuilding coord system")
|
||||
("precision", po::value<short>(&precision)->default_value(SerializerSettings::DEFAULT_PRECISION),
|
||||
"Sets the precision to be used to format floating-point values, 15 by default. "
|
||||
"Use a negative value to use the system's default precision (should be 6 typically). "
|
||||
@@ -341,7 +346,36 @@ int main(int argc, char** argv)
|
||||
|
||||
po::notify(vmap);
|
||||
|
||||
print_version();
|
||||
const bool mmap = vmap.count("mmap") != 0;
|
||||
const bool verbose = vmap.count("verbose") != 0;
|
||||
const bool no_progress = vmap.count("no-progress") != 0;
|
||||
const bool quiet = vmap.count("quiet") != 0;
|
||||
const bool weld_vertices = vmap.count("weld-vertices") != 0;
|
||||
const bool use_world_coords = vmap.count("use-world-coords") != 0;
|
||||
const bool convert_back_units = vmap.count("convert-back-units") != 0;
|
||||
const bool sew_shells = vmap.count("sew-shells") != 0;
|
||||
#if OCC_VERSION_HEX < 0x60900
|
||||
const bool merge_boolean_operands = vmap.count("merge-boolean-operands") != 0;
|
||||
#endif
|
||||
const bool disable_opening_subtractions = vmap.count("disable-opening-subtractions") != 0;
|
||||
const bool include_plan = vmap.count("plan") != 0;
|
||||
const bool include_model = vmap.count("model") != 0 || (!include_plan);
|
||||
const bool enable_layerset_slicing = vmap.count("enable-layerset-slicing") != 0;
|
||||
const bool use_element_names = vmap.count("use-element-names") != 0;
|
||||
const bool use_element_guids = vmap.count("use-element-guids") != 0;
|
||||
const bool use_material_names = vmap.count("use-material-names") != 0;
|
||||
const bool use_element_types = vmap.count("use-element-types") != 0;
|
||||
const bool use_element_hierarchy = vmap.count("use-element-hierarchy") != 0;
|
||||
const bool no_normals = vmap.count("no-normals") != 0;
|
||||
const bool center_model = vmap.count("center-model") != 0;
|
||||
const bool model_offset = vmap.count("model-offset") != 0;
|
||||
const bool site_local_placement = vmap.count("site-local-placement") != 0;
|
||||
const bool building_local_placement = vmap.count("building-local-placement") != 0;
|
||||
const bool generate_uvs = vmap.count("generate-uvs") != 0;
|
||||
|
||||
if (!quiet || vmap.count("version")) {
|
||||
print_version();
|
||||
}
|
||||
|
||||
if (vmap.count("version")) {
|
||||
return EXIT_SUCCESS;
|
||||
@@ -354,30 +388,6 @@ int main(int argc, char** argv)
|
||||
print_usage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
const bool mmap = vmap.count("mmap") != 0;
|
||||
const bool verbose = vmap.count("verbose") != 0;
|
||||
const bool no_progress = vmap.count("no-progress") != 0;
|
||||
const bool weld_vertices = vmap.count("weld-vertices") != 0;
|
||||
const bool use_world_coords = vmap.count("use-world-coords") != 0;
|
||||
const bool convert_back_units = vmap.count("convert-back-units") != 0;
|
||||
const bool sew_shells = vmap.count("sew-shells") != 0;
|
||||
#if OCC_VERSION_HEX < 0x60900
|
||||
const bool merge_boolean_operands = vmap.count("merge-boolean-operands") != 0;
|
||||
#endif
|
||||
const bool disable_opening_subtractions = vmap.count("disable-opening-subtractions") != 0;
|
||||
const bool include_plan = vmap.count("plan") != 0;
|
||||
const bool include_model = vmap.count("model") != 0 || (!include_plan);
|
||||
const bool enable_layerset_slicing = vmap.count("enable-layerset-slicing") != 0;
|
||||
const bool use_element_names = vmap.count("use-element-names") != 0;
|
||||
const bool use_element_guids = vmap.count("use-element-guids") != 0 ;
|
||||
const bool use_material_names = vmap.count("use-material-names") != 0;
|
||||
const bool use_element_types = vmap.count("use-element-types") != 0;
|
||||
const bool use_element_hierarchy = vmap.count("use-element-hierarchy") != 0;
|
||||
const bool no_normals = vmap.count("no-normals") != 0 ;
|
||||
const bool center_model = vmap.count("center-model") != 0 ;
|
||||
const bool model_offset = vmap.count("model-offset") != 0 ;
|
||||
const bool site_local_placement = vmap.count("site-local-placement") != 0 ;
|
||||
const bool generate_uvs = vmap.count("generate-uvs") != 0 ;
|
||||
|
||||
#ifdef HAVE_ICU
|
||||
if (!unicode_mode.empty()) {
|
||||
@@ -442,12 +452,25 @@ int main(int argc, char** argv)
|
||||
Logger::SetOutput(&std::cout, &log_stream);
|
||||
Logger::Verbosity(verbose ? Logger::LOG_NOTICE : Logger::LOG_ERROR);
|
||||
|
||||
if (vmap.count("log-format") == 1) {
|
||||
boost::to_lower(log_format);
|
||||
if (log_format == "plain") {
|
||||
Logger::OutputFormat(Logger::FMT_PLAIN);
|
||||
} else if (log_format == "json") {
|
||||
Logger::OutputFormat(Logger::FMT_JSON);
|
||||
} else {
|
||||
std::cerr << "[Error] --log-format should be either plain or json" << std::endl;
|
||||
print_usage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
IfcParse::IfcFile* ifc_file = 0;
|
||||
|
||||
if (output_extension == ".xml") {
|
||||
int exit_code = EXIT_FAILURE;
|
||||
try {
|
||||
if (init_input_file(input_filename, ifc_file, no_progress, mmap)) {
|
||||
if (init_input_file(input_filename, ifc_file, no_progress || quiet, mmap)) {
|
||||
XmlSerializer s(ifc_file, output_temp_filename);
|
||||
Logger::Status("Writing XML output...");
|
||||
s.finalize();
|
||||
@@ -458,7 +481,7 @@ int main(int argc, char** argv)
|
||||
} catch (const std::exception& e) {
|
||||
Logger::Error(e);
|
||||
}
|
||||
write_log();
|
||||
write_log(!quiet);
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
@@ -512,6 +535,8 @@ int main(int argc, char** argv)
|
||||
settings.set(IfcGeom::IteratorSettings::GENERATE_UVS, generate_uvs);
|
||||
settings.set(IfcGeom::IteratorSettings::SEARCH_FLOOR, use_element_hierarchy);
|
||||
settings.set(IfcGeom::IteratorSettings::SITE_LOCAL_PLACEMENT, site_local_placement);
|
||||
settings.set(IfcGeom::IteratorSettings::BUILDING_LOCAL_PLACEMENT, building_local_placement);
|
||||
|
||||
|
||||
settings.set(SerializerSettings::USE_ELEMENT_NAMES, use_element_names);
|
||||
settings.set(SerializerSettings::USE_ELEMENT_GUIDS, use_element_guids);
|
||||
@@ -551,7 +576,7 @@ int main(int argc, char** argv)
|
||||
}
|
||||
} else {
|
||||
std::cerr << "[Error] Unknown output filename extension '" + output_extension + "'\n";
|
||||
write_log();
|
||||
write_log(!quiet);
|
||||
print_usage();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@@ -560,7 +585,7 @@ int main(int argc, char** argv)
|
||||
|
||||
if (use_element_hierarchy && output_extension != ".dae") {
|
||||
std::cerr << "[Error] --use-element-hierarchy can be used only with .dae output.\n";
|
||||
write_log();
|
||||
write_log(!quiet);
|
||||
print_usage();
|
||||
delete serializer;
|
||||
std::remove(output_temp_filename.c_str()); /**< @todo Windows Unicode support */
|
||||
@@ -585,14 +610,14 @@ int main(int argc, char** argv)
|
||||
if (!serializer->ready()) {
|
||||
delete serializer;
|
||||
std::remove(output_temp_filename.c_str()); /**< @todo Windows Unicode support */
|
||||
write_log();
|
||||
write_log(!quiet);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
time_t start,end;
|
||||
time(&start);
|
||||
|
||||
if (!init_input_file(input_filename, ifc_file, no_progress, mmap)) {
|
||||
if (!init_input_file(input_filename, ifc_file, no_progress || quiet, mmap)) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -603,7 +628,7 @@ int main(int argc, char** argv)
|
||||
Logger::Error("No geometrical entities found");
|
||||
delete serializer;
|
||||
std::remove(output_temp_filename.c_str()); /**< @todo Windows Unicode support */
|
||||
write_log();
|
||||
write_log(!quiet);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -617,13 +642,13 @@ int main(int argc, char** argv)
|
||||
|
||||
serializer->writeHeader();
|
||||
|
||||
int old_progress = -1;
|
||||
int old_progress = quiet ? 0 : -1;
|
||||
|
||||
if (center_model || model_offset) {
|
||||
double* offset = serializer->settings().offset;
|
||||
if (center_model) {
|
||||
if (site_local_placement) {
|
||||
Logger::Error("Cannot use --center-model together with --site-local-placement");
|
||||
if (site_local_placement || building_local_placement) {
|
||||
Logger::Error("Cannot use --center-model together with --{site,building}-local-placement");
|
||||
delete serializer;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@@ -649,7 +674,9 @@ int main(int argc, char** argv)
|
||||
Logger::Notice(msg.str());
|
||||
}
|
||||
|
||||
Logger::Status("Creating geometry...");
|
||||
if (!quiet) {
|
||||
Logger::Status("Creating geometry...");
|
||||
}
|
||||
|
||||
// The functions IfcGeom::Iterator::get() and IfcGeom::Iterator::next()
|
||||
// wrap an iterator of all geometrical products in the Ifc file.
|
||||
@@ -676,14 +703,28 @@ int main(int argc, char** argv)
|
||||
}
|
||||
|
||||
if (!no_progress) {
|
||||
const int progress = context_iterator.progress() / 2;
|
||||
if (old_progress != progress) Logger::ProgressBar(progress);
|
||||
old_progress = progress;
|
||||
if (quiet) {
|
||||
const int progress = context_iterator.progress();
|
||||
for (; old_progress < progress; ++old_progress) {
|
||||
std::cout << ".";
|
||||
}
|
||||
std::cout << std::flush;
|
||||
} else {
|
||||
const int progress = context_iterator.progress() / 2;
|
||||
if (old_progress != progress) Logger::ProgressBar(progress);
|
||||
old_progress = progress;
|
||||
}
|
||||
}
|
||||
} while (++num_created, context_iterator.next());
|
||||
|
||||
Logger::Status("\rDone creating geometry (" + boost::lexical_cast<std::string>(num_created) +
|
||||
" objects) ");
|
||||
if (!no_progress && quiet) {
|
||||
for (; old_progress < 100; ++old_progress) {
|
||||
std::cout << ".";
|
||||
}
|
||||
} else {
|
||||
Logger::Status("\rDone creating geometry (" + boost::lexical_cast<std::string>(num_created) +
|
||||
" objects) ");
|
||||
}
|
||||
|
||||
serializer->finalize();
|
||||
delete serializer;
|
||||
@@ -696,34 +737,39 @@ int main(int argc, char** argv)
|
||||
output_temp_filename + "' for the conversion result.");
|
||||
}
|
||||
|
||||
write_log();
|
||||
write_log(!quiet);
|
||||
|
||||
time(&end);
|
||||
|
||||
int seconds = (int)difftime(end, start);
|
||||
std::stringstream msg;
|
||||
int minutes = seconds / 60;
|
||||
seconds = seconds % 60;
|
||||
msg << "\nConversion took";
|
||||
if (minutes > 0) {
|
||||
msg << " " << minutes << " minute";
|
||||
if (minutes > 1) {
|
||||
if (!quiet) {
|
||||
int seconds = (int)difftime(end, start);
|
||||
std::stringstream msg;
|
||||
int minutes = seconds / 60;
|
||||
seconds = seconds % 60;
|
||||
msg << "\nConversion took";
|
||||
if (minutes > 0) {
|
||||
msg << " " << minutes << " minute";
|
||||
if (minutes > 1) {
|
||||
msg << "s";
|
||||
}
|
||||
}
|
||||
msg << " " << seconds << " second";
|
||||
if (seconds > 1) {
|
||||
msg << "s";
|
||||
}
|
||||
Logger::Status(msg.str());
|
||||
}
|
||||
msg << " " << seconds << " second";
|
||||
if (seconds > 1) {
|
||||
msg << "s";
|
||||
}
|
||||
Logger::Status(msg.str());
|
||||
|
||||
return successful ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
void write_log() {
|
||||
void write_log(bool header) {
|
||||
std::string log = log_stream.str();
|
||||
if (!log.empty()) {
|
||||
std::cout << "\nLog:\n" << log << std::endl;
|
||||
if (header) {
|
||||
std::cout << "\nLog:\n";
|
||||
}
|
||||
std::cout << log << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -881,7 +927,7 @@ void validate(boost::any& v, const std::vector<std::string>& values, exclusion_t
|
||||
std::vector<IfcGeom::filter_t> setup_filters(const std::vector<geom_filter>& filters, const std::string& output_extension)
|
||||
{
|
||||
std::vector<IfcGeom::filter_t> filter_funcs;
|
||||
foreach(const geom_filter& f, filters) {
|
||||
BOOST_FOREACH(const geom_filter& f, filters) {
|
||||
if (f.type == geom_filter::ENTITY_TYPE) {
|
||||
entity_filter.include = f.include;
|
||||
entity_filter.traverse = f.traverse;
|
||||
|
||||
@@ -202,6 +202,8 @@ public:
|
||||
bool approximate_plane_through_wire(const TopoDS_Wire&, gp_Pln&);
|
||||
bool flatten_wire(TopoDS_Wire&);
|
||||
bool triangulate_wire(const TopoDS_Wire&, TopTools_ListOfShape&);
|
||||
bool wire_intersections(const TopoDS_Wire & wire, TopTools_ListOfShape & wires);
|
||||
void select_largest(const TopTools_ListOfShape& shapes, TopoDS_Shape& largest);
|
||||
|
||||
static double shape_volume(const TopoDS_Shape& s);
|
||||
static double face_area(const TopoDS_Face& f);
|
||||
|
||||
@@ -215,7 +215,15 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
|
||||
process_wire:
|
||||
|
||||
if (face_surface.IsNull()) {
|
||||
mf = new BRepBuilderAPI_MakeFace(wire);
|
||||
if (count(wire, TopAbs_EDGE) > 128) {
|
||||
// tfk: optimization find the underlying surface ourselves since it's going
|
||||
// to be planar in IFC if no explicit surface is given. Should we always do this?
|
||||
gp_Pln pln;
|
||||
approximate_plane_through_wire(wire, pln);
|
||||
mf = new BRepBuilderAPI_MakeFace(pln, wire, true);
|
||||
} else {
|
||||
mf = new BRepBuilderAPI_MakeFace(wire);
|
||||
}
|
||||
} else {
|
||||
/// @todo check necessity of false here
|
||||
mf = new BRepBuilderAPI_MakeFace(face_surface, wire, false);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "IfcGeom.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
@@ -90,7 +91,7 @@ namespace IfcGeom
|
||||
void populate(const std::set<std::string>& patterns)
|
||||
{
|
||||
values.clear();
|
||||
foreach(const std::string &pattern, patterns) {
|
||||
BOOST_FOREACH(const std::string &pattern, patterns) {
|
||||
values.insert(wildcard_string_to_regex(pattern));
|
||||
}
|
||||
}
|
||||
@@ -99,7 +100,7 @@ namespace IfcGeom
|
||||
|
||||
static bool match_values(const std::set<boost::regex>& values, const std::string &str)
|
||||
{
|
||||
foreach(const boost::regex& r, values) {
|
||||
BOOST_FOREACH(const boost::regex& r, values) {
|
||||
if (boost::regex_match(str, r)) {
|
||||
return true;
|
||||
}
|
||||
@@ -111,7 +112,7 @@ namespace IfcGeom
|
||||
{
|
||||
// Escape all non-"*?" regex special chars
|
||||
static const std::string special_chars = "\\^.$|()[]+/";
|
||||
foreach(char c, special_chars) {
|
||||
BOOST_FOREACH(char c, special_chars) {
|
||||
std::string char_str(1, c);
|
||||
boost::replace_all(str, char_str, "\\" + char_str);
|
||||
}
|
||||
@@ -184,7 +185,7 @@ namespace IfcGeom
|
||||
|
||||
ss << (traverse ? "traverse " : "") << (include ? "include" : "exclude");
|
||||
std::vector<std::string> patterns;
|
||||
foreach(const boost::regex& r, values) {
|
||||
BOOST_FOREACH(const boost::regex& r, values) {
|
||||
patterns.push_back("\"" + r.str() + "\"");
|
||||
}
|
||||
|
||||
@@ -247,7 +248,7 @@ namespace IfcGeom
|
||||
std::stringstream ss;
|
||||
ss << (traverse ? "traverse " : "") << (include ? "include" : "exclude") << " layers";
|
||||
std::vector<std::string> str_values;
|
||||
foreach(const boost::regex& r, values) {
|
||||
BOOST_FOREACH(const boost::regex& r, values) {
|
||||
str_values.push_back(" \"" + r.str() + "\"");
|
||||
}
|
||||
ss << boost::algorithm::join(str_values, " ");
|
||||
@@ -271,7 +272,7 @@ namespace IfcGeom
|
||||
// TODO
|
||||
#if 0
|
||||
values.clear();
|
||||
foreach(const std::string& type, types) {
|
||||
BOOST_FOREACH(const std::string& type, types) {
|
||||
const IfcParse::declaration* ty;
|
||||
try {
|
||||
ty = IfcSchema::FromString::Class()(boost::to_upper_copy(type));
|
||||
@@ -287,7 +288,7 @@ namespace IfcGeom
|
||||
bool match(IfcSchema::IfcProduct* prod) const
|
||||
{
|
||||
// The set is iterated over to able to filter on subtypes.
|
||||
foreach(const IfcParse::declaration* type, values) {
|
||||
BOOST_FOREACH(const IfcParse::declaration* type, values) {
|
||||
if (prod->declaration().is(*type)) {
|
||||
return true;
|
||||
}
|
||||
@@ -306,7 +307,7 @@ namespace IfcGeom
|
||||
#if 0
|
||||
std::stringstream ss;
|
||||
ss << (traverse ? "traverse " : "") << (include ? "include" : "exclude") << " entities";
|
||||
foreach(IfcSchema::Enum::Class() type, values) {
|
||||
BOOST_FOREACH(IfcSchema::Enum::Class() type, values) {
|
||||
ss << " " << IfcSchema::ToString::Class()(type);
|
||||
}
|
||||
description = ss.str();
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
#include <ShapeFix_Solid.hxx>
|
||||
|
||||
#include <ShapeAnalysis_Curve.hxx>
|
||||
#include <ShapeAnalysis_Wire.hxx>
|
||||
#include <ShapeAnalysis_Surface.hxx>
|
||||
#include <ShapeAnalysis_ShapeTolerance.hxx>
|
||||
|
||||
@@ -105,6 +106,7 @@
|
||||
#include <GProp_GProps.hxx>
|
||||
#include <BRepGProp.hxx>
|
||||
|
||||
#include <BRepBuilderAPI_Copy.hxx>
|
||||
#include <BRepBuilderAPI_Transform.hxx>
|
||||
#include <BRepBuilderAPI_GTransform.hxx>
|
||||
|
||||
@@ -131,6 +133,8 @@
|
||||
|
||||
#include <BRepClass3d_SolidClassifier.hxx>
|
||||
|
||||
#include <GeomAPI_ExtremaCurveCurve.hxx>
|
||||
|
||||
#include <Standard_Version.hxx>
|
||||
|
||||
#include "../ifcparse/macros.h"
|
||||
@@ -249,8 +253,10 @@ bool IfcGeom::Kernel::create_solid_from_faces(const TopTools_ListOfShape& face_l
|
||||
}
|
||||
|
||||
if (valid_shell) {
|
||||
|
||||
TopoDS_Shape complete_shape;
|
||||
TopExp_Explorer exp(shape, TopAbs_SHELL);
|
||||
|
||||
for (; exp.More(); exp.Next()) {
|
||||
TopoDS_Shape result_shape = exp.Current();
|
||||
|
||||
@@ -295,12 +301,28 @@ bool IfcGeom::Kernel::create_solid_from_faces(const TopTools_ListOfShape& face_l
|
||||
B.MakeCompound(C);
|
||||
B.Add(C, complete_shape);
|
||||
complete_shape = C;
|
||||
Logger::Message(Logger::LOG_WARNING, "Multiple components in IfcConnectedFaceSet");
|
||||
Logger::Message(Logger::LOG_ERROR, "Multiple components in IfcConnectedFaceSet");
|
||||
}
|
||||
B.Add(complete_shape, result_shape);
|
||||
}
|
||||
}
|
||||
|
||||
TopExp_Explorer loose_faces(shape, TopAbs_FACE, TopAbs_SHELL);
|
||||
|
||||
for (; loose_faces.More(); loose_faces.Next()) {
|
||||
BRep_Builder B;
|
||||
if (complete_shape.ShapeType() != TopAbs_COMPOUND) {
|
||||
TopoDS_Compound C;
|
||||
B.MakeCompound(C);
|
||||
B.Add(C, complete_shape);
|
||||
complete_shape = C;
|
||||
Logger::Message(Logger::LOG_ERROR, "Loose faces in IfcConnectedFaceSet");
|
||||
}
|
||||
B.Add(complete_shape, loose_faces.Current());
|
||||
}
|
||||
|
||||
shape = complete_shape;
|
||||
|
||||
} else {
|
||||
Logger::Message(Logger::LOG_WARNING, "Failed to sew faceset");
|
||||
}
|
||||
@@ -626,9 +648,12 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
|
||||
}
|
||||
|
||||
for ( unsigned int i = 0; i < opening_shapes.size(); ++ i ) {
|
||||
TopoDS_Shape opening_shape_solid;
|
||||
const TopoDS_Shape& opening_shape_unlocated = ensure_fit_for_subtraction(opening_shapes[i].Shape(), opening_shape_solid);
|
||||
|
||||
gp_GTrsf gtrsf = opening_shapes[i].Placement();
|
||||
gtrsf.PreMultiply(opening_trsf);
|
||||
TopoDS_Shape opening_shape = apply_transformation(opening_shapes[i].Shape(), gtrsf);
|
||||
TopoDS_Shape opening_shape = apply_transformation(opening_shape_unlocated, gtrsf);
|
||||
opening_shapelist.Append(opening_shape);
|
||||
}
|
||||
|
||||
@@ -657,7 +682,15 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
|
||||
}
|
||||
#endif
|
||||
|
||||
bool IfcGeom::Kernel::convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face) {
|
||||
bool IfcGeom::Kernel::convert_wire_to_face(const TopoDS_Wire& w, TopoDS_Face& face) {
|
||||
TopoDS_Wire wire = w;
|
||||
|
||||
TopTools_ListOfShape results;
|
||||
if (wire_intersections(wire, results)) {
|
||||
Logger::Error("Self-intersections with " + boost::lexical_cast<std::string>(results.Extent()) + " cycles detected");
|
||||
select_largest(results, wire);
|
||||
}
|
||||
|
||||
ShapeFix_ShapeTolerance FTol;
|
||||
FTol.SetTolerance(wire, getValue(GV_PRECISION), TopAbs_WIRE);
|
||||
|
||||
@@ -2429,7 +2462,11 @@ bool IfcGeom::Kernel::split_solid_by_shell(const TopoDS_Shape& input, const Topo
|
||||
}
|
||||
apply_tolerance(solid, getValue(GV_PRECISION));
|
||||
|
||||
#if OCC_VERSION_HEX >= 0x70300
|
||||
TopTools_ListOfShape shapes;
|
||||
#else
|
||||
BOPCol_ListOfShape shapes;
|
||||
#endif
|
||||
shapes.Append(input);
|
||||
shapes.Append(solid);
|
||||
BOPAlgo_PaveFiller filler(new NCollection_IncAllocator); // TODO: Does this need to be freed?
|
||||
@@ -2774,6 +2811,226 @@ TopoDS_Shape IfcGeom::Kernel::apply_transformation(const TopoDS_Shape& s, const
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
/*
|
||||
* A small helper utility to wrap around a numeric range
|
||||
*/
|
||||
class bounded_int {
|
||||
private:
|
||||
int i;
|
||||
size_t n;
|
||||
public:
|
||||
bounded_int(int i, size_t n) : i(i), n(n) {}
|
||||
|
||||
bounded_int& operator--() {
|
||||
--i;
|
||||
if (i == -1) {
|
||||
i = n - 1;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bounded_int& operator++() {
|
||||
++i;
|
||||
if (i == (int) n) {
|
||||
i = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator int() { return i; }
|
||||
};
|
||||
|
||||
std::string format_pnt(const gp_Pnt& p) {
|
||||
std::stringstream ss;
|
||||
ss << std::fixed << std::setprecision(4) << p.X() << " " << p.Y() << " " << p.Z();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string format_edge(const TopoDS_Edge& e) {
|
||||
std::stringstream ss;
|
||||
TopoDS_Vertex v1, v2;
|
||||
TopExp::Vertices(e, v1, v2);
|
||||
gp_Pnt p1 = BRep_Tool::Pnt(v1);
|
||||
gp_Pnt p2 = BRep_Tool::Pnt(v2);
|
||||
ss << "edge " << format_pnt(p1) << " -> " << format_pnt(p2);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::wire_intersections(const TopoDS_Wire& wire, TopTools_ListOfShape& wires) {
|
||||
if (!wire.Closed()) {
|
||||
wires.Append(wire);
|
||||
return false;
|
||||
}
|
||||
|
||||
int n = count(wire, TopAbs_EDGE);
|
||||
if (n < 3 || n > 128) {
|
||||
if (n > 128) {
|
||||
Logger::Notice("Too many segments for detection of self-intersections");
|
||||
}
|
||||
wires.Append(wire);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Note: initialize empty
|
||||
Handle(ShapeExtend_WireData) wd = new ShapeExtend_WireData();
|
||||
|
||||
// ... to be sure to get consecutive edges
|
||||
BRepTools_WireExplorer exp(wire);
|
||||
for (; exp.More(); exp.Next()) {
|
||||
wd->Add(exp.Current());
|
||||
}
|
||||
|
||||
bool intersected = false;
|
||||
|
||||
// tfk: Extrema on infinite curves proved to be more robust.
|
||||
// TopoDS_Face face = BRepBuilderAPI_MakeFace(wire, true).Face();
|
||||
// ShapeAnalysis_Wire saw(wd, face, getValue(GV_PRECISION));
|
||||
|
||||
for (int i = 2; i < n; ++i) {
|
||||
for (int j = 0; j < i - 1; ++j) {
|
||||
if (i == n - 1 && j == 0) continue;
|
||||
|
||||
bool unbounded_intersects;
|
||||
const double eps = getValue(GV_PRECISION) * 2.;
|
||||
|
||||
double u11, u12, u21, u22, U1, U2;
|
||||
GeomAPI_ExtremaCurveCurve ecc(
|
||||
BRep_Tool::Curve(wd->Edge(i + 1), u11, u12),
|
||||
BRep_Tool::Curve(wd->Edge(j + 1), u21, u22)
|
||||
);
|
||||
|
||||
if ((unbounded_intersects = (ecc.NbExtrema() == 1 && ecc.Distance(1) < eps))) {
|
||||
ecc.Parameters(1, U1, U2);
|
||||
}
|
||||
|
||||
if (u11 > u12) {
|
||||
std::swap(u11, u12);
|
||||
}
|
||||
if (u21 > u22) {
|
||||
std::swap(u21, u22);
|
||||
}
|
||||
|
||||
/// @todo: tfk: probably need different thresholds on non-linear curves
|
||||
u11 -= eps;
|
||||
u12 += eps;
|
||||
u21 -= eps;
|
||||
u22 += eps;
|
||||
|
||||
// tfk: code below is for ShapeAnalysis_Wire::CheckIntersectingEdges()
|
||||
// IntRes2d_SequenceOfIntersectionPoint points2d;
|
||||
// TColgp_SequenceOfPnt points3d;
|
||||
// TColStd_SequenceOfReal errors;
|
||||
// if (saw.CheckIntersectingEdges(i + 1, j + 1, points2d, points3d, errors)) {
|
||||
|
||||
if (unbounded_intersects && u11 < U1 && U1 < u12 && u21 < U2 && U2 < u22) {
|
||||
|
||||
intersected = true;
|
||||
|
||||
// Explore a forward and backward cycle from the intersection point
|
||||
for (int fb = 0; fb <= 1; ++fb) {
|
||||
const bool forward = fb == 0;
|
||||
|
||||
BRepBuilderAPI_MakeWire mw;
|
||||
bool first = true;
|
||||
|
||||
for (bounded_int k(j, n);;) {
|
||||
bool intersecting = k == j || k == i;
|
||||
if (intersecting) {
|
||||
TopoDS_Edge e = wd->Edge(k + 1);
|
||||
|
||||
TopoDS_Vertex v1, v2;
|
||||
TopExp::Vertices(e, v1, v2);
|
||||
const TopoDS_Vertex* v = first == forward ? &v2 : &v1;
|
||||
|
||||
// gp_Pnt p2 = points3d.Value(1);
|
||||
|
||||
gp_Pnt p1 = BRep_Tool::Pnt(*v);
|
||||
gp_Pnt pp1, pp2;
|
||||
ecc.Points(1, pp1, pp2);
|
||||
const gp_Pnt& p2 = k == i ? pp1 : pp2;
|
||||
|
||||
// Substitute with a new edge from/to the intersection point
|
||||
if (p1.Distance(p2) > getValue(GV_PRECISION) * 2) {
|
||||
double _, __;
|
||||
Handle_Geom_Curve crv = BRep_Tool::Curve(e, _, __);
|
||||
BRepBuilderAPI_MakeEdge me(crv, p1, p2);
|
||||
TopoDS_Edge ed = me.Edge();
|
||||
mw.Add(ed);
|
||||
}
|
||||
|
||||
first = false;
|
||||
} else {
|
||||
// Re-use original edge
|
||||
mw.Add(wd->Edge(k+1));
|
||||
}
|
||||
|
||||
if (k == i) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (forward) {
|
||||
++k;
|
||||
} else {
|
||||
--k;
|
||||
}
|
||||
}
|
||||
|
||||
// Recursively process both cuts
|
||||
wire_intersections(mw.Wire(), wires);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No intersections found, append original wire
|
||||
if (!intersected) {
|
||||
wires.Append(wire);
|
||||
}
|
||||
|
||||
return intersected;
|
||||
}
|
||||
|
||||
void IfcGeom::Kernel::select_largest(const TopTools_ListOfShape& shapes, TopoDS_Shape& largest) {
|
||||
double mass = 0.;
|
||||
TopTools_ListIteratorOfListOfShape it(shapes);
|
||||
for (; it.More(); it.Next()) {
|
||||
/*
|
||||
// tfk: bounding box is more efficient probably
|
||||
const TopoDS_Wire& w = TopoDS::Wire(it.Value());
|
||||
TopoDS_Face face = BRepBuilderAPI_MakeFace(w).Face();
|
||||
const double m = face_area(face);
|
||||
*/
|
||||
|
||||
Bnd_Box bb;
|
||||
BRepBndLib::AddClose(it.Value(), bb);
|
||||
double xyz_min[3], xyz_max[3];
|
||||
bb.Get(xyz_min[0], xyz_min[1], xyz_min[2], xyz_max[0], xyz_max[1], xyz_max[2]);
|
||||
const double eps = getValue(GV_PRECISION);
|
||||
|
||||
double m = 1.;
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
if (Precision::IsNegativeInfinite(xyz_min[i])) {
|
||||
xyz_min[i] = 0.;
|
||||
}
|
||||
if (Precision::IsInfinite(xyz_max[i])) {
|
||||
xyz_max[i] = 0.;
|
||||
}
|
||||
m *= (xyz_max[i] + eps) - (xyz_min[i] - eps);
|
||||
}
|
||||
|
||||
if (m > mass) {
|
||||
mass = m;
|
||||
largest = it.Value();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if OCC_VERSION_HEX < 0x60900
|
||||
bool IfcGeom::Kernel::boolean_operation(const TopoDS_Shape& a, const TopTools_ListOfShape& b, BOPAlgo_Operation op, TopoDS_Shape& result) {
|
||||
result = a;
|
||||
@@ -2832,6 +3089,47 @@ bool IfcGeom::Kernel::boolean_operation(const TopoDS_Shape& a, const TopoDS_Shap
|
||||
return succesful;
|
||||
}
|
||||
#else
|
||||
|
||||
namespace {
|
||||
TopTools_ListOfShape copy_operand(const TopTools_ListOfShape& l) {
|
||||
#if OCC_VERSION_HEX < 0x70000
|
||||
TopTools_ListOfShape r;
|
||||
TopTools_ListIteratorOfListOfShape it(l);
|
||||
for (; it.More(); it.Next()) {
|
||||
r.Append(BRepBuilderAPI_Copy(it.Value()));
|
||||
}
|
||||
return r;
|
||||
#else
|
||||
// On OCCT 7.0 and higher BRepAlgoAPI_BuilderAlgo::SetNonDestructive(true) is
|
||||
// called. Not entirely sure on the behaviour before 7.0, so overcautiously
|
||||
// create copies.
|
||||
return l;
|
||||
#endif
|
||||
}
|
||||
|
||||
TopoDS_Shape copy_operand(const TopoDS_Shape& s) {
|
||||
#if OCC_VERSION_HEX < 0x70000
|
||||
return BRepBuilderAPI_Copy(s);
|
||||
#else
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
double min_edge_length(const TopoDS_Shape& a) {
|
||||
double min_edge_len = std::numeric_limits<double>::infinity();
|
||||
TopExp_Explorer exp(a, TopAbs_EDGE);
|
||||
for (; exp.More(); exp.Next()) {
|
||||
GProp_GProps prop;
|
||||
BRepGProp::LinearProperties(exp.Current(), prop);
|
||||
double l = prop.Mass();
|
||||
if (l < min_edge_len) {
|
||||
min_edge_len = l;
|
||||
}
|
||||
}
|
||||
return min_edge_len;
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::boolean_operation(const TopoDS_Shape& a, const TopTools_ListOfShape& b, BOPAlgo_Operation op, TopoDS_Shape& result, double fuzziness) {
|
||||
bool success = false;
|
||||
BRepAlgoAPI_BooleanOperation* builder;
|
||||
@@ -2847,17 +3145,27 @@ bool IfcGeom::Kernel::boolean_operation(const TopoDS_Shape& a, const TopTools_Li
|
||||
if (fuzziness < 0.) {
|
||||
fuzziness = getValue(GV_PRECISION);
|
||||
}
|
||||
|
||||
const double min_edge_len = min_edge_length(a);
|
||||
const double fuzz = (std::min)(min_edge_len / 3., fuzziness);
|
||||
|
||||
TopTools_ListOfShape s1s;
|
||||
s1s.Append(a);
|
||||
builder->SetFuzzyValue(fuzziness);
|
||||
s1s.Append(copy_operand(a));
|
||||
#if OCC_VERSION_HEX >= 0x70000
|
||||
builder->SetNonDestructive(true);
|
||||
#endif
|
||||
builder->SetFuzzyValue(fuzz);
|
||||
builder->SetArguments(s1s);
|
||||
builder->SetTools(b);
|
||||
builder->SetTools(copy_operand(b));
|
||||
builder->Build();
|
||||
if (builder->IsDone()) {
|
||||
TopoDS_Shape r = *builder;
|
||||
|
||||
ShapeFix_Shape fix(r);
|
||||
try {
|
||||
fix.SetMinTolerance(fuzz);
|
||||
fix.SetMaxTolerance(fuzz);
|
||||
fix.SetPrecision(fuzz);
|
||||
fix.Perform();
|
||||
r = fix.Shape();
|
||||
} catch (...) {
|
||||
@@ -2873,7 +3181,7 @@ bool IfcGeom::Kernel::boolean_operation(const TopoDS_Shape& a, const TopTools_Li
|
||||
delete builder;
|
||||
if (!success) {
|
||||
const double new_fuzziness = fuzziness * 10.;
|
||||
if (new_fuzziness + 1e-15 <= getValue(GV_PRECISION) * 1000.) {
|
||||
if (new_fuzziness + 1e-15 <= getValue(GV_PRECISION) * 1000. && new_fuzziness < min_edge_len) {
|
||||
return boolean_operation(a, b, op, result, new_fuzziness);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,6 +119,9 @@ namespace IfcGeom {
|
||||
IfcSchema::IfcProduct::list::ptr ifcproducts;
|
||||
IfcSchema::IfcProduct::list::it ifcproduct_iterator;
|
||||
|
||||
|
||||
IfcSchema::IfcRepresentation::list::ptr ok_mapped_representations;
|
||||
|
||||
int done;
|
||||
int total;
|
||||
|
||||
@@ -192,6 +195,7 @@ namespace IfcGeom {
|
||||
bool any_precision_encountered = false;
|
||||
|
||||
representations = IfcSchema::IfcRepresentation::list::ptr(new IfcSchema::IfcRepresentation::list);
|
||||
ok_mapped_representations = IfcSchema::IfcRepresentation::list::ptr(new IfcSchema::IfcRepresentation::list);
|
||||
|
||||
IfcSchema::IfcGeometricRepresentationContext::list::it it;
|
||||
IfcSchema::IfcGeometricRepresentationSubContext::list::it jt;
|
||||
@@ -389,6 +393,7 @@ namespace IfcGeom {
|
||||
|
||||
// Note that this can be a nullptr (!), but the fact that set size should be one still holds
|
||||
associated_single_materials.insert(kernel.get_single_material_association(product));
|
||||
if (associated_single_materials.size() > 1) return false;
|
||||
}
|
||||
|
||||
return associated_single_materials.size() == 1;
|
||||
@@ -412,12 +417,20 @@ namespace IfcGeom {
|
||||
|
||||
geometry_reuse_ok_for_current_representation_ = reuse_ok_(unfiltered_products);
|
||||
|
||||
if (!geometry_reuse_ok_for_current_representation_ && representation->RepresentationMap()->size() == 1) {
|
||||
IfcSchema::IfcRepresentationMap::list::ptr maps = representation->RepresentationMap();
|
||||
|
||||
if (!geometry_reuse_ok_for_current_representation_ && maps->size() == 1) {
|
||||
// unfiltered_products contains products represented by this representation by means of mapped items.
|
||||
// For example because of openings applied to products, reuse might not be acceptable and then the
|
||||
// products will be processed by means of their immediate representation and not the mapped representation.
|
||||
_nextShape();
|
||||
continue;
|
||||
|
||||
// IfcRepresentationMaps are also used for IfcTypeProducts, so an additional check is performed whether the map
|
||||
// is indeed used by IfcMappedItems.
|
||||
IfcSchema::IfcRepresentationMap* map = *maps->begin();
|
||||
if (map->MapUsage()->size() > 0) {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
bool representation_processed_as_mapped_item = false;
|
||||
@@ -425,10 +438,12 @@ namespace IfcGeom {
|
||||
IfcSchema::IfcRepresentation* representation_mapped_to = kernel.representation_mapped_to(representation);
|
||||
if (representation_mapped_to) {
|
||||
// Check if this represenation has (or will be) processed as part its mapped representation
|
||||
representation_processed_as_mapped_item = reuse_ok_(kernel.products_represented_by(representation_mapped_to));
|
||||
representation_processed_as_mapped_item = ok_mapped_representations->contains(representation_mapped_to) ||
|
||||
reuse_ok_(kernel.products_represented_by(representation_mapped_to));
|
||||
}
|
||||
|
||||
if (representation_processed_as_mapped_item) {
|
||||
ok_mapped_representations->push(representation_mapped_to);
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
@@ -688,7 +703,12 @@ namespace IfcGeom {
|
||||
kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.get(IteratorSettings::SEW_SHELLS) ? 1000 : -1);
|
||||
kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.get(IteratorSettings::INCLUDE_CURVES)
|
||||
? (settings.get(IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES) ? -1. : 0.) : +1.));
|
||||
if (settings.get(IteratorSettings::SITE_LOCAL_PLACEMENT)) {
|
||||
if (settings.get(IteratorSettings::BUILDING_LOCAL_PLACEMENT)) {
|
||||
if (settings.get(IteratorSettings::SITE_LOCAL_PLACEMENT)) {
|
||||
Logger::Message(Logger::LOG_WARNING, "building-local-placement takes precedence over site-local-placement");
|
||||
}
|
||||
kernel.set_conversion_placement_rel_to(&IfcSchema::IfcBuilding::Class());
|
||||
} else if (settings.get(IteratorSettings::SITE_LOCAL_PLACEMENT)) {
|
||||
kernel.set_conversion_placement_rel_to(&IfcSchema::IfcSite::Class());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,8 +82,10 @@ namespace IfcGeom
|
||||
SEARCH_FLOOR = 1 << 14,
|
||||
///
|
||||
SITE_LOCAL_PLACEMENT = 1 << 15,
|
||||
/// Number of different setting flags.
|
||||
NUM_SETTINGS = 15
|
||||
///
|
||||
BUILDING_LOCAL_PLACEMENT = 1 << 16,
|
||||
/// Number of different setting flags.
|
||||
NUM_SETTINGS = 16
|
||||
};
|
||||
/// Used to store logical OR combination of setting flags.
|
||||
typedef unsigned SettingField;
|
||||
|
||||
@@ -551,7 +551,12 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape
|
||||
return false;
|
||||
}
|
||||
|
||||
#if OCC_VERSION_HEX < 0x60900
|
||||
bool valid_result = boolean_operation(s1, s2, occ_op, shape);
|
||||
#else
|
||||
const double fuzz = is_halfspace ? getValue(GV_PRECISION) * 10. : -1.;
|
||||
bool valid_result = boolean_operation(s1, s2, occ_op, shape, fuzz);
|
||||
#endif
|
||||
|
||||
if (op == IfcSchema::IfcBooleanOperator::IfcBooleanOperator_DIFFERENCE) {
|
||||
// In case of a subtraction, a check on volume is performed.
|
||||
|
||||
+198
-81
@@ -85,11 +85,169 @@
|
||||
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <BRepTools_WireExplorer.hxx>
|
||||
#include <ShapeBuild_ReShape.hxx>
|
||||
#include <TopTools_ListOfShape.hxx>
|
||||
#include <TopTools_ListIteratorOfListOfShape.hxx>
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
#define Kernel MAKE_TYPE_NAME(Kernel)
|
||||
|
||||
namespace {
|
||||
// Returns the other vertex of an edge
|
||||
TopoDS_Vertex other(const TopoDS_Edge& e, const TopoDS_Vertex& v) {
|
||||
TopoDS_Vertex a, b;
|
||||
TopExp::Vertices(e, a, b);
|
||||
return v.IsSame(b) ? a : b;
|
||||
}
|
||||
|
||||
TopoDS_Edge first_edge(const TopoDS_Wire& w) {
|
||||
TopoDS_Vertex v1, v2;
|
||||
TopExp::Vertices(w, v1, v2);
|
||||
TopTools_IndexedDataMapOfShapeListOfShape wm;
|
||||
TopExp::MapShapesAndAncestors(w, TopAbs_VERTEX, TopAbs_EDGE, wm);
|
||||
return TopoDS::Edge(wm.FindFromKey(v1).First());
|
||||
}
|
||||
|
||||
// Returns new wire with the edge replaced by a linear edge with the vertex v moved to p
|
||||
TopoDS_Wire adjust(const TopoDS_Wire& w, const TopoDS_Vertex& v, const gp_Pnt& p) {
|
||||
BRep_Builder b;
|
||||
TopoDS_Vertex v2;
|
||||
b.MakeVertex(v2, p, BRep_Tool::Tolerance(v));
|
||||
|
||||
ShapeBuild_ReShape reshape;
|
||||
reshape.Replace(v.Oriented(TopAbs_FORWARD), v2);
|
||||
|
||||
return TopoDS::Wire(reshape.Apply(w));
|
||||
}
|
||||
|
||||
// A wrapper around BRepBuilderAPI_MakeWire that makes sure segments are connected either by moving end points or by adding intermediate segments
|
||||
class wire_builder {
|
||||
private:
|
||||
BRepBuilderAPI_MakeWire mw_;
|
||||
double p_;
|
||||
bool override_next_;
|
||||
gp_Pnt next_override_;
|
||||
const IfcUtil::IfcBaseClass* inst_;
|
||||
|
||||
public:
|
||||
wire_builder(double p, const IfcUtil::IfcBaseClass* inst = 0) : p_(p), override_next_(false), inst_(inst) {}
|
||||
|
||||
void operator()(const TopoDS_Shape& a) {
|
||||
const TopoDS_Wire& w = TopoDS::Wire(a);
|
||||
if (override_next_) {
|
||||
override_next_ = false;
|
||||
TopoDS_Edge e = first_edge(w);
|
||||
mw_.Add(adjust(w, TopExp::FirstVertex(e, true), next_override_));
|
||||
} else {
|
||||
mw_.Add(w);
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(const TopoDS_Shape& a, const TopoDS_Shape& b, bool last) {
|
||||
TopoDS_Wire w1 = TopoDS::Wire(a);
|
||||
const TopoDS_Wire& w2 = TopoDS::Wire(b);
|
||||
|
||||
if (override_next_) {
|
||||
override_next_ = false;
|
||||
TopoDS_Edge e = first_edge(w1);
|
||||
w1 = adjust(w1, TopExp::FirstVertex(e, true), next_override_);
|
||||
}
|
||||
|
||||
TopoDS_Vertex w11, w12, w21, w22;
|
||||
TopExp::Vertices(w1, w11, w12);
|
||||
TopExp::Vertices(w2, w21, w22);
|
||||
|
||||
gp_Pnt p1 = BRep_Tool::Pnt(w12);
|
||||
gp_Pnt p2 = BRep_Tool::Pnt(w21);
|
||||
|
||||
double dist = p1.Distance(p2);
|
||||
|
||||
// Distance is within 2p, this is fine
|
||||
if (dist < p_) {
|
||||
mw_.Add(w1);
|
||||
goto check;
|
||||
}
|
||||
|
||||
// Distance is too large for attempting to move end points, add intermediate edge
|
||||
if (dist > 1000. * p_) {
|
||||
mw_.Add(w1);
|
||||
mw_.Add(BRepBuilderAPI_MakeEdge(p1, p2));
|
||||
Logger::Message(Logger::LOG_ERROR, "Added additional segment to close gap with length " + boost::lexical_cast<std::string>(dist) + " to:", inst_);
|
||||
goto check;
|
||||
}
|
||||
|
||||
{
|
||||
TopTools_IndexedDataMapOfShapeListOfShape wmap1, wmap2;
|
||||
|
||||
// Find edges connected to end- and begin vertex
|
||||
TopExp::MapShapesAndAncestors(w1, TopAbs_VERTEX, TopAbs_EDGE, wmap1);
|
||||
TopExp::MapShapesAndAncestors(w2, TopAbs_VERTEX, TopAbs_EDGE, wmap2);
|
||||
|
||||
const TopTools_ListOfShape& last_edges = wmap1.FindFromKey(w12);
|
||||
const TopTools_ListOfShape& first_edges = wmap2.FindFromKey(w21);
|
||||
|
||||
double _, __;
|
||||
if (last_edges.Extent() == 1 && first_edges.Extent() == 1) {
|
||||
Handle(Geom_Curve) c1 = BRep_Tool::Curve(TopoDS::Edge(last_edges.First()), _, __);
|
||||
Handle(Geom_Curve) c2 = BRep_Tool::Curve(TopoDS::Edge(first_edges.First()), _, __);
|
||||
|
||||
const bool is_line1 = c1->DynamicType() == STANDARD_TYPE(Geom_Line);
|
||||
const bool is_line2 = c2->DynamicType() == STANDARD_TYPE(Geom_Line);
|
||||
|
||||
// Adjust the segment that is linear
|
||||
if (is_line1) {
|
||||
mw_.Add(adjust(w1, w12, p2));
|
||||
Logger::Message(Logger::LOG_ERROR, "Adjusted edge end-point with distance " + boost::lexical_cast<std::string>(dist) + " on:", inst_);
|
||||
} else if (is_line2 && !last) {
|
||||
mw_.Add(w1);
|
||||
override_next_ = true;
|
||||
next_override_ = p1;
|
||||
Logger::Message(Logger::LOG_ERROR, "Adjusted edge end-point with distance " + boost::lexical_cast<std::string>(dist) + " on:", inst_);
|
||||
} else {
|
||||
// If both aren't linear an edge is added
|
||||
mw_.Add(w1);
|
||||
mw_.Add(BRepBuilderAPI_MakeEdge(p1, p2));
|
||||
Logger::Message(Logger::LOG_ERROR, "Added additional segment to close gap with length " + boost::lexical_cast<std::string>(dist) + " to:", inst_);
|
||||
}
|
||||
} else {
|
||||
Logger::Error("Internal error, inconsistent wire segments", inst_);
|
||||
mw_.Add(w1);
|
||||
}
|
||||
}
|
||||
|
||||
check:
|
||||
if (mw_.Error() == BRepBuilderAPI_NonManifoldWire) {
|
||||
Logger::Error("Non-manifold curve segments:", inst_);
|
||||
} else if (mw_.Error() == BRepBuilderAPI_DisconnectedWire) {
|
||||
Logger::Error("Failed to join curve segments:", inst_);
|
||||
}
|
||||
}
|
||||
|
||||
const TopoDS_Wire& wire() { return mw_.Wire(); }
|
||||
};
|
||||
|
||||
template <typename Fn>
|
||||
void shape_pair_enumerate(TopTools_ListIteratorOfListOfShape& it, Fn& fn, bool closed) {
|
||||
bool is_first = true;
|
||||
TopoDS_Shape first, previous, current;
|
||||
for (; it.More(); it.Next(), is_first = false) {
|
||||
current = it.Value();
|
||||
if (is_first) {
|
||||
first = current;
|
||||
} else {
|
||||
fn(previous, current, false);
|
||||
}
|
||||
previous = current;
|
||||
}
|
||||
if (closed) {
|
||||
fn(current, first, true);
|
||||
} else {
|
||||
fn(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wire& wire) {
|
||||
if ( getValue(GV_PLANEANGLE_UNIT)<0 ) {
|
||||
Logger::Message(Logger::LOG_WARNING,"Creating a composite curve without unit information:",l);
|
||||
@@ -167,105 +325,45 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wire
|
||||
return use_radians || use_degrees;
|
||||
}
|
||||
|
||||
BRepBuilderAPI_MakeWire w;
|
||||
TopoDS_Vertex wire_first_vertex, wire_last_vertex, edge_first_vertex, edge_last_vertex;
|
||||
|
||||
IfcSchema::IfcCompositeCurveSegment::list::ptr segments = l->Segments();
|
||||
|
||||
const double precision_sq_2 = 2 * getValue(GV_PRECISION) * getValue(GV_PRECISION);
|
||||
TopTools_ListOfShape converted_segments;
|
||||
|
||||
for(IfcSchema::IfcCompositeCurveSegment::list::it it = segments->begin(); it != segments->end(); ++it) {
|
||||
|
||||
for (IfcSchema::IfcCompositeCurveSegment::list::it it = segments->begin(); it != segments->end(); ++it) {
|
||||
|
||||
IfcSchema::IfcCurve* curve = (*it)->ParentCurve();
|
||||
TopoDS_Wire segment;
|
||||
|
||||
|
||||
if (!convert_wire(curve, segment)) {
|
||||
Logger::Message(Logger::LOG_ERROR, "Failed to convert curve:", curve);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (!(*it)->SameSense()) {
|
||||
segment.Reverse();
|
||||
}
|
||||
|
||||
|
||||
ShapeFix_ShapeTolerance FTol;
|
||||
FTol.SetTolerance(segment, getValue(GV_PRECISION), TopAbs_WIRE);
|
||||
|
||||
TopExp::Vertices(segment, edge_first_vertex, edge_last_vertex);
|
||||
|
||||
if (it == segments->begin()) {
|
||||
wire_first_vertex = edge_first_vertex;
|
||||
} else {
|
||||
gp_Pnt first = BRep_Tool::Pnt(edge_first_vertex);
|
||||
gp_Pnt last = BRep_Tool::Pnt(wire_last_vertex);
|
||||
converted_segments.Append(segment);
|
||||
|
||||
Standard_Real distance = first.SquareDistance(last);
|
||||
if (distance > precision_sq_2) {
|
||||
w.Add(BRepBuilderAPI_MakeEdge(wire_last_vertex, edge_first_vertex));
|
||||
|
||||
Logger::Message(Logger::LOG_ERROR, "Closed gap on:", l);
|
||||
}
|
||||
}
|
||||
|
||||
w.Add(segment);
|
||||
|
||||
if ( w.Error() != BRepBuilderAPI_WireDone ) {
|
||||
if (w.Error() == BRepBuilderAPI_NonManifoldWire) {
|
||||
|
||||
Logger::Message(Logger::LOG_ERROR, "Non-manifold curve segments:", l);
|
||||
|
||||
} else if (w.Error() == BRepBuilderAPI_DisconnectedWire) {
|
||||
|
||||
Logger::Message(Logger::LOG_ERROR, "Failed to join curve segments:", l);
|
||||
|
||||
gp_Pnt p1, p2;
|
||||
int precision = 4;
|
||||
double d = 0.;
|
||||
|
||||
if (!wire_last_vertex.IsNull()) {
|
||||
p1 = BRep_Tool::Pnt(wire_last_vertex);
|
||||
}
|
||||
if (!edge_first_vertex.IsNull()) {
|
||||
p2 = BRep_Tool::Pnt(edge_first_vertex);
|
||||
}
|
||||
if (!wire_last_vertex.IsNull() && !edge_first_vertex.IsNull()) {
|
||||
d = p1.Distance(p2);
|
||||
precision = ceil(-log10(d)) + 3;
|
||||
}
|
||||
|
||||
if (!wire_last_vertex.IsNull()) {
|
||||
std::stringstream ss;
|
||||
ss << std::setprecision(precision) << "Last vertex at (" << p1.X() << " " << p1.Y() << " " << p1.Z() << ")";
|
||||
Logger::Message(Logger::LOG_NOTICE, ss.str());
|
||||
}
|
||||
|
||||
if (!edge_first_vertex.IsNull()) {
|
||||
std::stringstream ss;
|
||||
ss << std::setprecision(precision) << "Segment starts at (" << p2.X() << " " << p2.Y() << " " << p2.Z() << ")";
|
||||
if (d > 0.) {
|
||||
ss << ", distance " << d << " > precision " << std::fixed << getValue(GV_PRECISION) / 10.;
|
||||
}
|
||||
ss << " for:";
|
||||
Logger::Message(Logger::LOG_NOTICE, ss.str(), (*it));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
wire_last_vertex = edge_last_vertex;
|
||||
}
|
||||
|
||||
gp_Pnt first = BRep_Tool::Pnt(edge_last_vertex);
|
||||
gp_Pnt last = BRep_Tool::Pnt(wire_first_vertex);
|
||||
BRepBuilderAPI_MakeWire w;
|
||||
TopoDS_Vertex wire_first_vertex, wire_last_vertex, edge_first_vertex, edge_last_vertex;
|
||||
|
||||
Standard_Real distance = first.SquareDistance(last);
|
||||
if (distance > precision_sq_2) {
|
||||
w.Add(BRepBuilderAPI_MakeEdge(edge_last_vertex, wire_first_vertex));
|
||||
const double precision_sq_2 = 2 * getValue(GV_PRECISION) * getValue(GV_PRECISION);
|
||||
|
||||
Logger::Message(Logger::LOG_ERROR, "Closed gap on:", l);
|
||||
}
|
||||
TopTools_ListIteratorOfListOfShape it(converted_segments);
|
||||
|
||||
wire = w.Wire();
|
||||
IfcEntityList::ptr profile = l->data().getInverse(&IfcSchema::IfcProfileDef::Class(), -1);
|
||||
const bool force_close = profile && profile->size() > 0;
|
||||
|
||||
wire_builder bld(getValue(GV_PRECISION), l);
|
||||
shape_pair_enumerate(it, bld, force_close);
|
||||
wire = bld.wire();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -395,14 +493,25 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcPolyline* l, TopoDS_Wire& resu
|
||||
polygon.Append(pnt);
|
||||
}
|
||||
|
||||
const double eps = getValue(GV_PRECISION) * 10;
|
||||
const bool closed_by_proximity = polygon.Length() >= 2 && polygon.First().Distance(polygon.Last()) < eps;
|
||||
if (closed_by_proximity) {
|
||||
// tfk: note 1-based
|
||||
polygon.Remove(polygon.Length());
|
||||
}
|
||||
|
||||
// Remove points that are too close to one another
|
||||
remove_duplicate_points_from_loop(polygon, false);
|
||||
remove_duplicate_points_from_loop(polygon, closed_by_proximity, eps);
|
||||
|
||||
BRepBuilderAPI_MakePolygon w;
|
||||
for (int i = 1; i <= polygon.Length(); ++i) {
|
||||
w.Add(polygon.Value(i));
|
||||
}
|
||||
|
||||
if (closed_by_proximity) {
|
||||
w.Close();
|
||||
}
|
||||
|
||||
result = w.Wire();
|
||||
return true;
|
||||
}
|
||||
@@ -426,7 +535,8 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcPolyLoop* l, TopoDS_Wire& resu
|
||||
}
|
||||
|
||||
// Remove points that are too close to one another
|
||||
remove_duplicate_points_from_loop(polygon, true);
|
||||
const double eps = getValue(GV_PRECISION) * 10;
|
||||
remove_duplicate_points_from_loop(polygon, true, eps);
|
||||
|
||||
int count = polygon.Length();
|
||||
if (original_count - count != 0) {
|
||||
@@ -445,7 +555,14 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcPolyLoop* l, TopoDS_Wire& resu
|
||||
}
|
||||
w.Close();
|
||||
|
||||
result = w.Wire();
|
||||
result = w.Wire();
|
||||
|
||||
TopTools_ListOfShape results;
|
||||
if (wire_intersections(result, results)) {
|
||||
Logger::Error("Self-intersections with " + boost::lexical_cast<std::string>(results.Extent()) + " cycles detected", l);
|
||||
select_largest(results, result);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,18 +12,24 @@ import OCC.AIS
|
||||
|
||||
from collections import defaultdict, Iterable, OrderedDict
|
||||
|
||||
os.environ['QT_API'] = 'pyqt4'
|
||||
try:
|
||||
QString = unicode
|
||||
except NameError:
|
||||
# Python 3
|
||||
QString = str
|
||||
|
||||
os.environ['QT_API'] = 'pyqt5'
|
||||
try:
|
||||
from pyqode.qt import QtCore
|
||||
except BaseException:
|
||||
pass
|
||||
|
||||
from PyQt4 import QtGui, QtCore
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from .code_editor_pane import code_edit
|
||||
|
||||
try:
|
||||
from OCC.Display.pyqt4Display import qtViewer3d
|
||||
from OCC.Display.pyqt5Display import qtViewer3d
|
||||
except BaseException:
|
||||
import OCC.Display
|
||||
|
||||
@@ -33,9 +39,9 @@ except BaseException:
|
||||
pass
|
||||
|
||||
try:
|
||||
OCC.Display.backend.get_backend("qt-pyqt4")
|
||||
OCC.Display.backend.get_backend("qt-pyqt5")
|
||||
except BaseException:
|
||||
OCC.Display.backend.load_backend("qt-pyqt4")
|
||||
OCC.Display.backend.load_backend("qt-pyqt5")
|
||||
|
||||
from OCC.Display.qtDisplay import qtViewer3d
|
||||
|
||||
@@ -43,14 +49,11 @@ from .main import settings, iterator
|
||||
from .occ_utils import display_shape
|
||||
|
||||
from .. import open as open_ifc_file
|
||||
from .. import get_supertype
|
||||
|
||||
# Depending on Python version and what not there may or may not be a QString
|
||||
try:
|
||||
from PyQt4.QtCore import QString
|
||||
except ImportError:
|
||||
QString = str
|
||||
from .. import version as ifcopenshell_version
|
||||
|
||||
if ifcopenshell_version < "0.6":
|
||||
# not yet ported
|
||||
from .. import get_supertype
|
||||
|
||||
class configuration(object):
|
||||
def __init__(self):
|
||||
@@ -113,11 +116,11 @@ if selection:
|
||||
return OrderedDict([(k, self.config_decode(self.config.get(s, k))) for k in self.config.options(s)])
|
||||
|
||||
|
||||
class application(QtGui.QApplication):
|
||||
class application(QtWidgets.QApplication):
|
||||
"""A pythonOCC, PyQt based IfcOpenShell application
|
||||
with two tree views and a graphical 3d view"""
|
||||
|
||||
class abstract_treeview(QtGui.QTreeWidget):
|
||||
class abstract_treeview(QtWidgets.QTreeWidget):
|
||||
|
||||
"""Base class for the two treeview controls"""
|
||||
|
||||
@@ -126,7 +129,7 @@ class application(QtGui.QApplication):
|
||||
instanceDisplayModeChanged = QtCore.pyqtSignal([object, int])
|
||||
|
||||
def __init__(self):
|
||||
QtGui.QTreeView.__init__(self)
|
||||
QtWidgets.QTreeView.__init__(self)
|
||||
self.setColumnCount(len(self.ATTRIBUTES))
|
||||
self.setHeaderLabels(self.ATTRIBUTES)
|
||||
self.children = defaultdict(list)
|
||||
@@ -140,23 +143,23 @@ class application(QtGui.QApplication):
|
||||
return c
|
||||
|
||||
def contextMenuEvent(self, event):
|
||||
menu = QtGui.QMenu(self)
|
||||
menu = QtWidgets.QMenu(self)
|
||||
visibility = [menu.addAction("Show"), menu.addAction("Hide")]
|
||||
displaymode = [menu.addAction("Solid"), menu.addAction("Wireframe")]
|
||||
action = menu.exec_(self.mapToGlobal(event.pos()))
|
||||
index = self.selectionModel().currentIndex()
|
||||
inst = index.data(QtCore.Qt.UserRole)
|
||||
if hasattr(inst, 'toPyObject'):
|
||||
inst = inst.toPyObject()
|
||||
inst = inst
|
||||
if action in visibility:
|
||||
self.instanceVisibilityChanged.emit(inst, visibility.index(action))
|
||||
elif action in displaymode:
|
||||
self.instanceDisplayModeChanged.emit(inst, displaymode.index(action))
|
||||
|
||||
def clicked(self, index):
|
||||
def clicked_(self, index):
|
||||
inst = index.data(QtCore.Qt.UserRole)
|
||||
if hasattr(inst, 'toPyObject'):
|
||||
inst = inst.toPyObject()
|
||||
inst = inst
|
||||
if inst:
|
||||
self.instanceSelected.emit(inst)
|
||||
|
||||
@@ -165,7 +168,7 @@ class application(QtGui.QApplication):
|
||||
if itm is None:
|
||||
return
|
||||
self.selectionModel().setCurrentIndex(itm,
|
||||
QtGui.QItemSelectionModel.SelectCurrent | QtGui.QItemSelectionModel.Rows)
|
||||
QtCore.QItemSelectionModel.SelectCurrent | QtCore.QItemSelectionModel.Rows)
|
||||
|
||||
class decomposition_treeview(abstract_treeview):
|
||||
|
||||
@@ -206,11 +209,11 @@ class application(QtGui.QApplication):
|
||||
sl.append(product.is_a())
|
||||
else:
|
||||
sl.append(getattr(product, attr) or '')
|
||||
itm = items[product] = QtGui.QTreeWidgetItem(items.get(parent, self), sl)
|
||||
itm = items[product] = QtWidgets.QTreeWidgetItem(items.get(parent, self), sl)
|
||||
itm.setData(0, QtCore.Qt.UserRole, product)
|
||||
self.children[parent].append(product)
|
||||
self.product_to_item = dict(zip(items.keys(), map(self.indexFromItem, items.values())))
|
||||
self.connect(self, QtCore.SIGNAL("clicked(const QModelIndex &)"), self.clicked)
|
||||
self.clicked.connect(self.clicked_)
|
||||
self.expandAll()
|
||||
|
||||
class type_treeview(abstract_treeview):
|
||||
@@ -230,33 +233,34 @@ class application(QtGui.QApplication):
|
||||
add(s)
|
||||
s2, t2 = map(QString, (s, t))
|
||||
if t2 not in items:
|
||||
itm = items[t2] = QtGui.QTreeWidgetItem(items.get(s2, self), [t2])
|
||||
itm = items[t2] = QtWidgets.QTreeWidgetItem(items.get(s2, self), [t2])
|
||||
itm.setData(0, QtCore.Qt.UserRole, t2)
|
||||
self.children[s2].append(t2)
|
||||
|
||||
add(t)
|
||||
if ifcopenshell_version < "0.6":
|
||||
add(t)
|
||||
|
||||
for p in products:
|
||||
t = QString(p.is_a())
|
||||
itm = items[p] = QtGui.QTreeWidgetItem(items.get(t, self), [p.Name or '<no name>'])
|
||||
itm = items[p] = QtWidgets.QTreeWidgetItem(items.get(t, self), [p.Name or '<no name>'])
|
||||
itm.setData(0, QtCore.Qt.UserRole, t)
|
||||
self.children[t].append(p)
|
||||
|
||||
self.product_to_item = dict(zip(items.keys(), map(self.indexFromItem, items.values())))
|
||||
self.connect(self, QtCore.SIGNAL("clicked(const QModelIndex &)"), self.clicked)
|
||||
self.clicked.connect(self.clicked)
|
||||
self.expandAll()
|
||||
|
||||
class property_table(QtGui.QWidget):
|
||||
class property_table(QtWidgets.QWidget):
|
||||
|
||||
def __init__(self):
|
||||
QtGui.QWidget.__init__(self)
|
||||
self.layout = QtGui.QVBoxLayout(self)
|
||||
QtWidgets.QWidget.__init__(self)
|
||||
self.layout = QtWidgets.QVBoxLayout(self)
|
||||
self.setLayout(self.layout)
|
||||
self.scroll = QtGui.QScrollArea(self)
|
||||
self.scroll = QtWidgets.QScrollArea(self)
|
||||
self.layout.addWidget(self.scroll)
|
||||
self.scroll.setWidgetResizable(True)
|
||||
self.scrollContent = QtGui.QWidget(self.scroll)
|
||||
self.scrollLayout = QtGui.QVBoxLayout(self.scrollContent)
|
||||
self.scrollContent = QtWidgets.QWidget(self.scroll)
|
||||
self.scrollLayout = QtWidgets.QVBoxLayout(self.scrollContent)
|
||||
self.scrollContent.setLayout(self.scrollLayout)
|
||||
self.scroll.setWidget(self.scrollContent)
|
||||
self.prop_dict = {}
|
||||
@@ -271,17 +275,17 @@ class application(QtGui.QApplication):
|
||||
if child.widget() is not None:
|
||||
child.widget().deleteLater()
|
||||
|
||||
self.scroll = QtGui.QScrollArea()
|
||||
self.scroll = QtWidgets.QScrollArea()
|
||||
self.scroll.setWidgetResizable(True)
|
||||
|
||||
prop_sets = self.prop_dict.get(str(product))
|
||||
|
||||
if prop_sets is not None:
|
||||
for k, v in prop_sets:
|
||||
group_box = QtGui.QGroupBox()
|
||||
group_box = QtWidgets.QGroupBox()
|
||||
|
||||
group_box.setTitle(k)
|
||||
group_layout = QtGui.QVBoxLayout()
|
||||
group_layout = QtWidgets.QVBoxLayout()
|
||||
group_box.setLayout(group_layout)
|
||||
|
||||
for name, value in v.items():
|
||||
@@ -300,7 +304,7 @@ class application(QtGui.QApplication):
|
||||
type_str = " <i>(%s)</i>" % value.is_a()
|
||||
else:
|
||||
type_str = ""
|
||||
label = QtGui.QLabel("<b>%s</b>: %s%s" % (prop_name, value_str, type_str))
|
||||
label = QtWidgets.QLabel("<b>%s</b>: %s%s" % (prop_name, value_str, type_str))
|
||||
group_layout.addWidget(label)
|
||||
|
||||
group_layout.addStretch()
|
||||
@@ -308,7 +312,7 @@ class application(QtGui.QApplication):
|
||||
|
||||
self.scrollLayout.addStretch()
|
||||
else:
|
||||
label = QtGui.QLabel("No IfcPropertySets asscociated with selected entity instance")
|
||||
label = QtWidgets.QLabel("No IfcPropertySets asscociated with selected entity instance")
|
||||
self.scrollLayout.addWidget(label)
|
||||
|
||||
def load_file(self, f, **kwargs):
|
||||
@@ -431,7 +435,7 @@ class application(QtGui.QApplication):
|
||||
self.ais_to_product[self.counter] = product
|
||||
self.product_to_ais[product] = ais
|
||||
self.counter += 1
|
||||
QtGui.QApplication.processEvents()
|
||||
QtWidgets.QApplication.processEvents()
|
||||
if product.is_a() in {'IfcSpace', 'IfcOpeningElement'}:
|
||||
v.Context.Erase(ais, True)
|
||||
progress = it.progress() // 2
|
||||
@@ -493,14 +497,14 @@ class application(QtGui.QApplication):
|
||||
inst = self.ais_to_product[ais.GetObject().SelectionPriority()]
|
||||
self.instanceSelected.emit(inst)
|
||||
|
||||
class window(QtGui.QMainWindow):
|
||||
class window(QtWidgets.QMainWindow):
|
||||
|
||||
TITLE = "IfcOpenShell IFC viewer"
|
||||
|
||||
window_closed = QtCore.pyqtSignal([])
|
||||
|
||||
def __init__(self):
|
||||
QtGui.QMainWindow.__init__(self)
|
||||
QtWidgets.QMainWindow.__init__(self)
|
||||
self.setWindowTitle(self.TITLE)
|
||||
self.menu = self.menuBar()
|
||||
self.menus = {}
|
||||
@@ -515,9 +519,9 @@ class application(QtGui.QApplication):
|
||||
self.menus[menu] = m
|
||||
|
||||
if icon:
|
||||
a = QtGui.QAction(QtGui.QIcon(icon), label, self)
|
||||
a = QtWidgets.QAction(QtGui.QIcon(icon), label, self)
|
||||
else:
|
||||
a = QtGui.QAction(label, self)
|
||||
a = QtWidgets.QAction(label, self)
|
||||
|
||||
if shortcut:
|
||||
a.setShortcut(shortcut)
|
||||
@@ -534,20 +538,20 @@ class application(QtGui.QApplication):
|
||||
return handler
|
||||
|
||||
def __init__(self, settings=None):
|
||||
QtGui.QApplication.__init__(self, sys.argv)
|
||||
QtWidgets.QApplication.__init__(self, sys.argv)
|
||||
self.window = application.window()
|
||||
self.tree = application.decomposition_treeview()
|
||||
self.tree2 = application.type_treeview()
|
||||
self.propview = self.property_table()
|
||||
self.canvas = application.viewer(self.window)
|
||||
self.tabs = QtGui.QTabWidget()
|
||||
self.tabs = QtWidgets.QTabWidget()
|
||||
self.window.resize(800, 600)
|
||||
splitter = QtGui.QSplitter(QtCore.Qt.Horizontal)
|
||||
splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
|
||||
splitter.addWidget(self.tabs)
|
||||
self.tabs.addTab(self.tree, 'Decomposition')
|
||||
self.tabs.addTab(self.tree2, 'Types')
|
||||
self.tabs.addTab(self.propview, "Properties")
|
||||
splitter2 = QtGui.QSplitter(QtCore.Qt.Vertical)
|
||||
splitter2 = QtWidgets.QSplitter(QtCore.Qt.Vertical)
|
||||
splitter2.addWidget(self.canvas)
|
||||
self.editor = code_edit(self.canvas, configuration().options('snippets'))
|
||||
splitter2.addWidget(self.editor)
|
||||
@@ -585,8 +589,8 @@ class application(QtGui.QApplication):
|
||||
sys.exit(self.exec_())
|
||||
|
||||
def browse(self):
|
||||
filename = QtGui.QFileDialog.getOpenFileName(self.window, 'Open file', ".",
|
||||
"Industry Foundation Classes (*.ifc)")
|
||||
filename = QtWidgets.QFileDialog.getOpenFileName(self.window, 'Open file', ".",
|
||||
"Industry Foundation Classes (*.ifc)")[0]
|
||||
self.load(filename)
|
||||
|
||||
def clear(self):
|
||||
|
||||
@@ -7,10 +7,10 @@ import sys
|
||||
import logging
|
||||
|
||||
from code import InteractiveConsole
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
try:
|
||||
from PyQt4 import QtWidgets
|
||||
from PyQt5 import QtWidgets
|
||||
except BaseException:
|
||||
QtWidgets = QtGui
|
||||
|
||||
@@ -32,23 +32,23 @@ except BaseException:
|
||||
|
||||
|
||||
class StdoutRedirector(object):
|
||||
'''A class for redirecting stdout to this Text widget.'''
|
||||
"""A class for redirecting stdout to this Text widget."""
|
||||
|
||||
def __init__(self, widget):
|
||||
self.widget = widget
|
||||
self.isError = False
|
||||
|
||||
def write(self, str):
|
||||
def write(self, myStr):
|
||||
self.widget.moveCursor(QtGui.QTextCursor.End)
|
||||
if self.isError:
|
||||
self.widget.setTextColor(QtCore.Qt.red)
|
||||
else:
|
||||
self.widget.setTextColor(QtCore.Qt.white)
|
||||
self.widget.insertPlainText(str)
|
||||
self.widget.insertPlainText(myStr)
|
||||
self.widget.moveCursor(QtGui.QTextCursor.End)
|
||||
|
||||
|
||||
class code_edit(QtGui.QWidget):
|
||||
class code_edit(QtWidgets.QWidget):
|
||||
class Console(InteractiveConsole):
|
||||
def __init__(*args):
|
||||
InteractiveConsole.__init__(*args)
|
||||
@@ -73,18 +73,15 @@ class code_edit(QtGui.QWidget):
|
||||
self.c = self.Console({'model': self.model, 'viewer': self.viewer, 'selection': product})
|
||||
|
||||
def __init__(self, viewer, snippets=None):
|
||||
|
||||
self.model = None
|
||||
self.viewer = viewer
|
||||
QtGui.QWidget.__init__(self)
|
||||
self.layout = QtGui.QVBoxLayout(self)
|
||||
QtWidgets.QWidget.__init__(self)
|
||||
self.layout = QtWidgets.QVBoxLayout(self)
|
||||
self.setLayout(self.layout)
|
||||
self.c = None
|
||||
|
||||
self.tools = QtGui.QHBoxLayout(self)
|
||||
self.tools = QtWidgets.QHBoxLayout(self)
|
||||
self.layout.addLayout(self.tools)
|
||||
|
||||
self.runbutton = QtGui.QPushButton("Run")
|
||||
self.runbutton = QtWidgets.QPushButton("Run")
|
||||
width = self.runbutton.fontMetrics().boundingRect("Run").width() + 20
|
||||
self.runbutton.setMaximumWidth(width)
|
||||
self.tools.addWidget(self.runbutton)
|
||||
@@ -129,11 +126,10 @@ class code_edit(QtGui.QWidget):
|
||||
for snip_name in self.snippets.keys():
|
||||
self.list.addItem(snip_name)
|
||||
self.tools.addWidget(self.list)
|
||||
QtCore.QObject.connect(self.list, QtCore.SIGNAL("currentIndexChanged(int)"), self.replace_snippet)
|
||||
self.list.currentIndexChanged[int].connect(self.replace_snippet)
|
||||
|
||||
self.layout.addWidget(self.editor)
|
||||
|
||||
self.output = QtGui.QTextEdit()
|
||||
self.output = QtWidgets.QTextEdit()
|
||||
self.output.setReadOnly(True)
|
||||
self.output.setStyleSheet('font-size: 10pt; font-family: Consolas, Courier; background-color: #444;')
|
||||
self.layout.addWidget(self.output)
|
||||
|
||||
@@ -133,7 +133,7 @@ def display_shape(shape, clr=None, viewer_handle=None):
|
||||
if isinstance(clr, tuple) and len(clr) == 4 and clr[3] < 1.:
|
||||
ais.SetTransparency(1. - clr[3])
|
||||
|
||||
elif representation:
|
||||
elif representation and hasattr(OCC.AIS, "AIS_MultipleConnectedShape"):
|
||||
default_style_applied = None
|
||||
|
||||
ais = OCC.AIS.AIS_MultipleConnectedShape(shape)
|
||||
|
||||
@@ -38,10 +38,6 @@
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/dynamic_bitset.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#define foreach BOOST_FOREACH
|
||||
#define rforeach BOOST_REVERSE_FOREACH
|
||||
|
||||
class Argument;
|
||||
class IfcEntityList;
|
||||
|
||||
@@ -70,6 +70,10 @@
|
||||
using namespace IfcParse;
|
||||
using namespace IfcWrite;
|
||||
|
||||
#ifdef HAVE_ICU
|
||||
#include <unicode/unistr.h>
|
||||
#endif
|
||||
|
||||
void IfcCharacterDecoder::addChar(std::stringstream& s,const UChar32& ch) {
|
||||
#ifdef HAVE_ICU
|
||||
if ( destination ) {
|
||||
@@ -386,4 +390,4 @@ IfcCharacterEncoder::operator std::string() {
|
||||
#ifdef HAVE_ICU
|
||||
UErrorCode IfcCharacterEncoder::status = U_ZERO_ERROR;
|
||||
UConverter* IfcCharacterEncoder::converter = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -65,7 +65,7 @@ public:
|
||||
|
||||
virtual ~IfcEntityInstanceData();
|
||||
|
||||
boost::shared_ptr<IfcEntityList> getInverse(const IfcParse::declaration* type, int attribute_index);
|
||||
boost::shared_ptr<IfcEntityList> getInverse (const IfcParse::declaration* type, int attribute_index) const;
|
||||
|
||||
Argument* getArgument(unsigned int i) const;
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <boost/unordered_map.hpp>
|
||||
|
||||
#include "ifc_parse_api.h"
|
||||
|
||||
@@ -36,7 +37,7 @@ namespace IfcParse {
|
||||
class IFC_PARSE_API IfcFile {
|
||||
public:
|
||||
typedef std::map<const IfcParse::declaration*, IfcEntityList::ptr> entities_by_type_t;
|
||||
typedef std::map<unsigned int, IfcUtil::IfcBaseClass*> entity_by_id_t;
|
||||
typedef boost::unordered_map<unsigned int, IfcUtil::IfcBaseClass*> entity_by_id_t;
|
||||
typedef std::map<std::string, IfcUtil::IfcBaseClass*> entity_by_guid_t;
|
||||
typedef std::map<unsigned int, std::vector<unsigned int> > entities_by_ref_t;
|
||||
typedef entity_by_id_t::const_iterator const_iterator;
|
||||
|
||||
+49
-12
@@ -25,9 +25,44 @@
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/json_parser.hpp>
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
|
||||
using boost::property_tree::ptree;
|
||||
|
||||
namespace {
|
||||
static const char* severity_strings[] = {"Notice", "Warning", "Error"};
|
||||
|
||||
void plain_text_message(std::ostream& os, const boost::optional<IfcUtil::IfcBaseClass*>& current_product, Logger::Severity type, const std::string& message, const IfcUtil::IfcBaseClass* instance) {
|
||||
os << "[" << severity_strings[type] << "] ";
|
||||
if (current_product) {
|
||||
std::string global_id = *(**current_product).data().getArgument((**current_product).declaration().as_entity()->attribute_index("GlobalId"));
|
||||
os << "{" << global_id << "} ";
|
||||
}
|
||||
os << message << std::endl;
|
||||
if (instance) {
|
||||
os << instance->data().toString() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void json_message(std::ostream& os, const boost::optional<IfcUtil::IfcBaseClass*>& current_product, Logger::Severity type, const std::string& message, const IfcUtil::IfcBaseClass* instance) {
|
||||
ptree pt;
|
||||
pt.put("level", severity_strings[type]);
|
||||
if (current_product) {
|
||||
pt.put("product", (**current_product).data().toString());
|
||||
}
|
||||
pt.put("message", message);
|
||||
if (instance) {
|
||||
pt.put("instance", instance->data().toString());
|
||||
}
|
||||
boost::property_tree::write_json(os, pt, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::SetOutput(std::ostream* l1, std::ostream* l2) {
|
||||
log1 = l1;
|
||||
log2 = l2;
|
||||
@@ -37,15 +72,11 @@ void Logger::SetOutput(std::ostream* l1, std::ostream* l2) {
|
||||
}
|
||||
|
||||
void Logger::Message(Logger::Severity type, const std::string& message, const IfcUtil::IfcBaseClass* instance) {
|
||||
if ( log2 && type >= verbosity ) {
|
||||
(*log2) << "[" << severity_strings[type] << "] ";
|
||||
if ( current_product ) {
|
||||
std::string global_id = *(**current_product).data().getArgument((**current_product).declaration().as_entity()->attribute_index("GlobalId"));
|
||||
(*log2) << "{" << global_id << "} ";
|
||||
}
|
||||
(*log2) << message << std::endl;
|
||||
if (instance) {
|
||||
(*log2) << instance->data().toString() << std::endl;
|
||||
if (log2 && type >= verbosity) {
|
||||
if (format == FMT_PLAIN) {
|
||||
plain_text_message(*log2, current_product, type, message, instance);
|
||||
} else if (format == FMT_JSON) {
|
||||
json_message(*log2, current_product, type, message, instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,26 +86,32 @@ void Logger::Message(Logger::Severity type, const std::exception& exception, con
|
||||
}
|
||||
|
||||
void Logger::Status(const std::string& message, bool new_line) {
|
||||
if ( log1 ) {
|
||||
if (log1) {
|
||||
(*log1) << message;
|
||||
if ( new_line ) (*log1) << std::endl;
|
||||
else (*log1) << std::flush;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::ProgressBar(int progress) {
|
||||
if ( log1 ) {
|
||||
if (log1) {
|
||||
Status("\r[" + std::string(progress,'#') + std::string(50 - progress,' ') + "]", false);
|
||||
}
|
||||
}
|
||||
|
||||
std::string Logger::GetLog() {
|
||||
return log_stream.str();
|
||||
}
|
||||
|
||||
void Logger::Verbosity(Logger::Severity v) { verbosity = v; }
|
||||
Logger::Severity Logger::Verbosity() { return verbosity; }
|
||||
|
||||
void Logger::OutputFormat(Format f) { format = f; }
|
||||
Logger::Format Logger::OutputFormat() { return format; }
|
||||
|
||||
std::ostream* Logger::log1 = 0;
|
||||
std::ostream* Logger::log2 = 0;
|
||||
std::stringstream Logger::log_stream;
|
||||
Logger::Severity Logger::verbosity = Logger::LOG_NOTICE;
|
||||
const char* Logger::severity_strings[] = { "Notice","Warning","Error" };
|
||||
Logger::Format Logger::format = Logger::FMT_PLAIN;
|
||||
boost::optional<IfcUtil::IfcBaseClass*> Logger::current_product;
|
||||
|
||||
@@ -36,12 +36,13 @@
|
||||
class IFC_PARSE_API Logger {
|
||||
public:
|
||||
typedef enum { LOG_NOTICE, LOG_WARNING, LOG_ERROR } Severity;
|
||||
typedef enum { FMT_PLAIN, FMT_JSON } Format;
|
||||
private:
|
||||
static std::ostream* log1;
|
||||
static std::ostream* log2;
|
||||
static std::stringstream log_stream;
|
||||
static Severity verbosity;
|
||||
static const char* severity_strings[];
|
||||
static Format format;
|
||||
static boost::optional<IfcUtil::IfcBaseClass*> current_product;
|
||||
public:
|
||||
|
||||
@@ -51,9 +52,14 @@ public:
|
||||
|
||||
/// Determines to what stream respectively progress and errors are logged
|
||||
static void SetOutput(std::ostream* l1, std::ostream* l2);
|
||||
|
||||
/// Determines the types of log messages to get logged
|
||||
static void Verbosity(Severity v);
|
||||
static Severity Verbosity();
|
||||
|
||||
/// Determines output format: plain text or sequence of JSON objects
|
||||
static void OutputFormat(Format f);
|
||||
static Format OutputFormat();
|
||||
|
||||
/// Log a message to the output stream
|
||||
static void Message(Severity type, const std::string& message, const IfcUtil::IfcBaseClass* instance = 0);
|
||||
|
||||
+17
-12
@@ -988,7 +988,7 @@ unsigned IfcEntityInstanceData::set_id(boost::optional<unsigned> i) {
|
||||
//
|
||||
// Returns the entities of Entity type that have this entity in their ArgumentList
|
||||
//
|
||||
IfcEntityList::ptr IfcEntityInstanceData::getInverse(const IfcParse::declaration* type, int attribute_index) {
|
||||
IfcEntityList::ptr IfcEntityInstanceData::getInverse(const IfcParse::declaration* type, int attribute_index) const {
|
||||
return file->getInverse(id_, type, attribute_index);
|
||||
}
|
||||
|
||||
@@ -1891,7 +1891,7 @@ IfcEntityList::ptr IfcFile::instances_by_reference(int t) {
|
||||
IfcUtil::IfcBaseClass* IfcFile::instance_by_id(int id) {
|
||||
entity_by_id_t::const_iterator it = byid.find(id);
|
||||
if (it == byid.end()) {
|
||||
throw IfcException("Entity not found");
|
||||
throw IfcException("Instance #" + boost::lexical_cast<std::string>(id) + " not found");
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
@@ -1899,7 +1899,7 @@ IfcUtil::IfcBaseClass* IfcFile::instance_by_id(int id) {
|
||||
IfcUtil::IfcBaseClass* IfcFile::instance_by_guid(const std::string& guid) {
|
||||
entity_by_guid_t::const_iterator it = byguid.find(guid);
|
||||
if ( it == byguid.end() ) {
|
||||
throw IfcException("Entity not found");
|
||||
throw IfcException("Instance with GlobalId '" + guid + "' not found");
|
||||
} else {
|
||||
return it->second;
|
||||
}
|
||||
@@ -1980,15 +1980,20 @@ IfcEntityList::ptr IfcFile::getInverse(int instance_id, const IfcParse::declarat
|
||||
for(IfcEntityList::it it = all->begin(); it != all->end(); ++it) {
|
||||
bool valid = type == 0 || (*it)->declaration().is(*type);
|
||||
if (valid && attribute_index >= 0) {
|
||||
Argument* arg = (*it)->data().getArgument(attribute_index);
|
||||
if (arg->type() == IfcUtil::Argument_ENTITY_INSTANCE) {
|
||||
valid = instance == *arg;
|
||||
} else if (arg->type() == IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE) {
|
||||
IfcEntityList::ptr li = *arg;
|
||||
valid = li->contains(instance);
|
||||
} else if (arg->type() == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE) {
|
||||
IfcEntityListList::ptr li = *arg;
|
||||
valid = li->contains(instance);
|
||||
try {
|
||||
Argument* arg = (*it)->data().getArgument(attribute_index);
|
||||
if (arg->type() == IfcUtil::Argument_ENTITY_INSTANCE) {
|
||||
valid = instance == *arg;
|
||||
} else if (arg->type() == IfcUtil::Argument_AGGREGATE_OF_ENTITY_INSTANCE) {
|
||||
IfcEntityList::ptr li = *arg;
|
||||
valid = li->contains(instance);
|
||||
} else if (arg->type() == IfcUtil::Argument_AGGREGATE_OF_AGGREGATE_OF_ENTITY_INSTANCE) {
|
||||
IfcEntityListList::ptr li = *arg;
|
||||
valid = li->contains(instance);
|
||||
}
|
||||
} catch (const IfcException& e) {
|
||||
valid = false;
|
||||
Logger::Error(e);
|
||||
}
|
||||
}
|
||||
if (valid) {
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#include "ColladaSerializer.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <COLLADASWPrimitves.h>
|
||||
#include <COLLADASWSource.h>
|
||||
#include <COLLADASWScene.h>
|
||||
@@ -223,7 +225,7 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add(
|
||||
node.addMatrix(matrix_array);
|
||||
COLLADASW::InstanceGeometry instanceGeometry(mSW);
|
||||
instanceGeometry.setUrl ("#" + geom_name);
|
||||
foreach(std::string material_name, material_ids) {
|
||||
BOOST_FOREACH(std::string material_name, material_ids) {
|
||||
/// @todo This is done 6 times in this file, try to perform this once and be done with the material naming for the export.
|
||||
collada_id(material_name);
|
||||
COLLADASW::InstanceMaterial material (material_name, "#" + material_name);
|
||||
@@ -362,7 +364,7 @@ bool ColladaSerializer::ColladaExporter::ColladaMaterials::contains(const IfcGeo
|
||||
|
||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::write() {
|
||||
effects.close();
|
||||
foreach(const IfcGeom::Material& material, materials) {
|
||||
BOOST_FOREACH(const IfcGeom::Material& material, materials) {
|
||||
std::string material_name = (serializer->settings().get(SerializerSettings::USE_MATERIAL_NAMES)
|
||||
? material.original_name() : material.name());
|
||||
std::string material_name_unescaped = material_name; // workaround double-escaping that would occur in addInstanceEffect()
|
||||
@@ -408,7 +410,7 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme
|
||||
collada_id(representation_id);
|
||||
|
||||
std::vector<std::string> material_references;
|
||||
foreach(const IfcGeom::Material& material, mesh.materials()) {
|
||||
BOOST_FOREACH(const IfcGeom::Material& material, mesh.materials()) {
|
||||
if (!materials.contains(material)) {
|
||||
materials.add(material);
|
||||
}
|
||||
|
||||
@@ -360,26 +360,26 @@ void SvgSerializer::write(const IfcGeom::BRepElement<real_t>* o)
|
||||
if (pnt.Z() < zmin) { zmin = pnt.Z(); }
|
||||
if (pnt.Z() > zmax) { zmax = pnt.Z(); }
|
||||
}}
|
||||
|
||||
if (section_height) {
|
||||
if (zmin > section_height || zmax < section_height) continue;
|
||||
} else {
|
||||
if (zmin == inf || (zmax - zmin) < 1.) continue;
|
||||
}
|
||||
|
||||
// Priority:
|
||||
// 1) section_height
|
||||
// 2) Storey elevation + 1m
|
||||
// 3) zmin + 1m
|
||||
|
||||
// Empty geometry, no vertices encountered
|
||||
if (zmin == inf) continue;
|
||||
|
||||
// Determine slicing plane z coordinate, priority:
|
||||
// 1) explicitly set global section height
|
||||
// 2) containing building storey elevation + 1m
|
||||
// 3) zmin (from geometry bounding box) + 1m
|
||||
double cut_z;
|
||||
if (section_height) {
|
||||
cut_z = section_height.get();
|
||||
} else if (storey_elevation) {
|
||||
} else if (storey_elevation && !(zmin > *storey_elevation || zmax < *storey_elevation)) {
|
||||
cut_z = storey_elevation.get() + 1.;
|
||||
} else {
|
||||
cut_z = zmin + 1.;
|
||||
}
|
||||
|
||||
// No intersection with bounding box, fail early
|
||||
if (zmin > cut_z || zmax < cut_z) continue;
|
||||
|
||||
// Create a horizontal cross section 1 meter above the bottom point of the shape
|
||||
TopoDS_Shape result = BRepAlgoAPI_Section(subshape, gp_Pln(gp_Pnt(0, 0, cut_z), gp::DZ()));
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
#include <boost/property_tree/xml_parser.hpp>
|
||||
#include <boost/version.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "XmlSerializer.h"
|
||||
|
||||
@@ -279,6 +280,9 @@ ptree& descend(IfcSchema::IfcObjectDefinition* product, ptree& tree) {
|
||||
if (pset->declaration().is(IfcSchema::IfcElementQuantity::Class())) {
|
||||
format_entity_instance(pset, child, true);
|
||||
}
|
||||
if (pset->declaration().is(IfcSchema::IfcElementQuantity::Class())) {
|
||||
format_entity_instance(pset, child, true);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_IFC4
|
||||
@@ -358,16 +362,16 @@ void MAKE_TYPE_NAME(XmlSerializer)::finalize() {
|
||||
ptree root, header, units, decomposition, properties, quantities, types, layers, materials;
|
||||
|
||||
// Write the SPF header as XML nodes.
|
||||
foreach(const std::string& s, file->header().file_description().description()) {
|
||||
BOOST_FOREACH(const std::string& s, file->header().file_description().description()) {
|
||||
header.add_child("file_description.description", ptree(s));
|
||||
}
|
||||
foreach(const std::string& s, file->header().file_name().author()) {
|
||||
BOOST_FOREACH(const std::string& s, file->header().file_name().author()) {
|
||||
header.add_child("file_name.author", ptree(s));
|
||||
}
|
||||
foreach(const std::string& s, file->header().file_name().organization()) {
|
||||
BOOST_FOREACH(const std::string& s, file->header().file_name().organization()) {
|
||||
header.add_child("file_name.organization", ptree(s));
|
||||
}
|
||||
foreach(const std::string& s, file->header().file_schema().schema_identifiers()) {
|
||||
BOOST_FOREACH(const std::string& s, file->header().file_schema().schema_identifiers()) {
|
||||
header.add_child("file_schema.schema_identifiers", ptree(s));
|
||||
}
|
||||
header.put("file_description.implementation_level", file->header().file_description().implementation_level());
|
||||
@@ -450,8 +454,11 @@ void MAKE_TYPE_NAME(XmlSerializer)::finalize() {
|
||||
emitted_materials.insert(mat);
|
||||
ptree node;
|
||||
node.put("<xmlattr>.id", qualify_unrooted_instance(mat));
|
||||
if (mat->as<IfcSchema::IfcMaterialLayerSetUsage>()) {
|
||||
IfcSchema::IfcMaterialLayerSet* layerset = mat->as<IfcSchema::IfcMaterialLayerSetUsage>()->ForLayerSet();
|
||||
if (mat->as<IfcSchema::IfcMaterialLayerSetUsage>() || mat->as<IfcSchema::IfcMaterialLayerSet>()) {
|
||||
IfcSchema::IfcMaterialLayerSet* layerset = mat->as<IfcSchema::IfcMaterialLayerSet>();
|
||||
if (!layerset) {
|
||||
layerset = mat->as<IfcSchema::IfcMaterialLayerSetUsage>()->ForLayerSet();
|
||||
}
|
||||
if (layerset->hasLayerSetName()) {
|
||||
node.put("<xmlattr>.LayerSetName", layerset->LayerSetName());
|
||||
}
|
||||
|
||||
+59
-30
@@ -85,6 +85,14 @@ FOR %%i IN (powershell git cmake) DO (
|
||||
where.exe %%i 1> NUL 2> NUL || call cecho.cmd 0 12 "Required tool `'%%i`' not installed or not added to PATH" && goto :ErrorAndPrintUsage
|
||||
)
|
||||
|
||||
cmake --version | findstr version > temp.txt
|
||||
set /p CMAKE_VERSION=<temp.txt
|
||||
del temp.txt
|
||||
if "%CMAKE_VERSION%" LSS "cmake version 3.11.4" (
|
||||
echo "CMake v3.11.4 or higher is required"
|
||||
goto :ErrorAndPrintUsage
|
||||
)
|
||||
|
||||
:: Print build configuration information
|
||||
|
||||
call cecho.cmd 0 10 "Script configuration:"
|
||||
@@ -124,7 +132,7 @@ echo.
|
||||
call cecho.cmd black cyan "If you are not ready with the above: type `'n`' in the prompt below. Build proceeds on all other inputs!"
|
||||
|
||||
set /p do_continue="> "
|
||||
if "%do_continue%"==n goto :Finish
|
||||
if "%do_continue%"=="n" goto :Finish
|
||||
|
||||
:: Cache last used CMake generator for other scripts to use
|
||||
if defined GEN_SHORTHAND echo GEN_SHORTHAND=%GEN_SHORTHAND%>"%~dp0\BuildDepsCache-%TARGET_ARCH%.txt"
|
||||
@@ -141,31 +149,28 @@ cd "%DEPS_DIR%"
|
||||
:: by modifying this file and using goto.
|
||||
:Boost
|
||||
:: NOTE Boost < 1.64 doesn't work without tricks if the user has only VS 2017 installed and no earlier versions.
|
||||
set BOOST_VERSION=1.65.1
|
||||
:: DEPENDENCY_NAME is used for logging and DEPENDENCY_DIR for saving from some redundant typing
|
||||
set DEPENDENCY_NAME=Boost %BOOST_VERSION%
|
||||
set DEPENDENCY_DIR="%DEPS_DIR%\boost"
|
||||
set BOOST_VERSION=1.67.0
|
||||
:: Version string with underscores instead of dots.
|
||||
set BOOST_VER=%BOOST_VERSION:.=_%
|
||||
REM set BOOST_ROOT=%DEPS_DIR%\boost
|
||||
REM set BOOST_INCLUDEDIR=%DEPS_DIR%\boost
|
||||
set BOOST_LIBRARYDIR=%DEPS_DIR%\boost\stage\%VS_PLATFORM%\lib
|
||||
:: DEPENDENCY_NAME is used for logging and DEPENDENCY_DIR for saving from some redundant typing
|
||||
set DEPENDENCY_NAME=Boost %BOOST_VERSION%
|
||||
set DEPENDENCY_DIR="%DEPS_DIR%\boost_%BOOST_VER%"
|
||||
set BOOST_LIBRARYDIR=%DEPENDENCY_DIR%\stage\%VS_PLATFORM%\lib
|
||||
:: NOTE Also zip download exists, if encountering problems with 7z for some reason.
|
||||
set ZIP_EXT=7z
|
||||
set BOOST_ZIP=boost_%BOOST_VER%.%ZIP_EXT%
|
||||
|
||||
call :DownloadFile http://downloads.sourceforge.net/project/boost/boost/%BOOST_VERSION%/%BOOST_ZIP% "%DEPS_DIR%" %BOOST_ZIP%
|
||||
call :DownloadFile https://dl.bintray.com/boostorg/release/%BOOST_VERSION%/source/%BOOST_ZIP% "%DEPS_DIR%" %BOOST_ZIP%
|
||||
|
||||
IF NOT %ERRORLEVEL%==0 GOTO :Error
|
||||
call :ExtractArchive %BOOST_ZIP% "%DEPS_DIR%" "%DEPS_DIR%\boost"
|
||||
call :ExtractArchive %BOOST_ZIP% "%DEPS_DIR%" "%DEPENDENCY_DIR%"
|
||||
IF NOT %ERRORLEVEL%==0 GOTO :Error
|
||||
|
||||
:: Build Boost build script
|
||||
if not exist "%DEPS_DIR%\boost\project-config.jam". (
|
||||
if not exist "%DEPENDENCY_DIR%\project-config.jam". (
|
||||
cd "%DEPS_DIR%"
|
||||
ren boost_%BOOST_VER% boost
|
||||
IF NOT EXIST "%DEPS_DIR%\boost\boost.css" GOTO :Error
|
||||
cd "%DEPS_DIR%\boost"
|
||||
IF NOT EXIST "%DEPENDENCY_DIR%\boost.css" GOTO :Error
|
||||
cd "%DEPENDENCY_DIR%"
|
||||
call cecho.cmd 0 13 "Building Boost build script."
|
||||
call bootstrap msvc
|
||||
IF NOT %ERRORLEVEL%==0 GOTO :Error
|
||||
@@ -173,9 +178,9 @@ if not exist "%DEPS_DIR%\boost\project-config.jam". (
|
||||
|
||||
set BOOST_LIBS=--with-system --with-regex --with-thread --with-program_options --with-date_time --with-iostreams --with-filesystem
|
||||
:: NOTE Boost is fast to build with limited set of libraries so build it always.
|
||||
cd "%DEPS_DIR%\boost"
|
||||
cd "%DEPENDENCY_DIR%"
|
||||
call cecho.cmd 0 13 "Building %DEPENDENCY_NAME% %BOOST_LIBS% Please be patient, this will take a while."
|
||||
IF EXIST "%DEPS_DIR%\boost\bin.v2\project-cache.jam" del "%DEPS_DIR%\boost\bin.v2\project-cache.jam"
|
||||
IF EXIST "%DEPENDENCY_DIR%\bin.v2\project-cache.jam" del "%DEPS_DIR%\boost\bin.v2\project-cache.jam"
|
||||
:: BOOST_VC_VER can be empty (or needs to be) for newer VS versions
|
||||
set BOOST_VC_VER=
|
||||
if %VS_VER% LSS 2017 (
|
||||
@@ -192,7 +197,7 @@ set DEPENDENCY_DIR=N/A
|
||||
set ICU_VER=58.2
|
||||
set ICU_ZIP=icu-%ICU_VER%-vs%VS_VER%.7z
|
||||
cd "%DEPS_DIR%"
|
||||
call :DownloadFile http://www.npcglib.org/~stathis/downloads/%ICU_ZIP% "%DEPS_DIR%" %ICU_ZIP%
|
||||
call :DownloadFile https://www.npcglib.org/~stathis/downloads/%ICU_ZIP% "%DEPS_DIR%" %ICU_ZIP%
|
||||
IF NOT %ERRORLEVEL%==0 GOTO :Error
|
||||
call :ExtractArchive %ICU_ZIP% "%DEPS_DIR%" "%INSTALL_DIR%\icu"
|
||||
IF NOT %ERRORLEVEL%==0 GOTO :Error
|
||||
@@ -267,11 +272,13 @@ if not %ERRORLEVEL%==0 goto :Error
|
||||
call :InstallCMakeProject "%DEPENDENCY_DIR%\%BUILD_DIR%" %BUILD_CFG%
|
||||
if not %ERRORLEVEL%==0 goto :Error
|
||||
|
||||
set DEPENDENCY_NAME=Open CASCADE 7.1.0
|
||||
set OCCT_FILENAME=occt-89aebde
|
||||
set OCCT_HASH=88af392
|
||||
set OCCT_VERSION=7.2.0
|
||||
set DEPENDENCY_NAME=Open CASCADE %OCCT_VERSION%
|
||||
set OCCT_FILENAME=occt-%OCCT_HASH%
|
||||
set DEPENDENCY_DIR=%DEPS_DIR%\%OCCT_FILENAME%
|
||||
cd "%DEPS_DIR%"
|
||||
call :DownloadFile "http://git.dev.opencascade.org/gitweb/?p=occt.git;a=snapshot;h=89aebde;sf=tgz" "%DEPS_DIR%" %OCCT_FILENAME%.tar.gz
|
||||
call :DownloadFile "http://git.dev.opencascade.org/gitweb/?p=occt.git;a=snapshot;h=%OCCT_HASH%;sf=tgz" "%DEPS_DIR%" %OCCT_FILENAME%.tar.gz
|
||||
if not %ERRORLEVEL%==0 goto :Error
|
||||
|
||||
if exist "%DEPS_DIR%\%OCCT_FILENAME%" (
|
||||
@@ -280,6 +287,7 @@ if exist "%DEPS_DIR%\%OCCT_FILENAME%" (
|
||||
if not exist "%DEPS_DIR%\%OCCT_FILENAME%\OCCT_LGPL_EXCEPTION.txt". rd /s/q "%DEPS_DIR%\%OCCT_FILENAME%"
|
||||
)
|
||||
|
||||
|
||||
call :ExtractArchive %OCCT_FILENAME%.tar.gz "%DEPS_DIR%" "%DEPENDENCY_DIR%"
|
||||
if not %ERRORLEVEL%==0 goto :Error
|
||||
call :ExtractArchive %OCCT_FILENAME%.tar "%DEPS_DIR%" "%DEPENDENCY_DIR%"
|
||||
@@ -288,24 +296,45 @@ if not %ERRORLEVEL%==0 goto :Error
|
||||
set DEPENDENCY_NAME=Additional files
|
||||
:: Somehow these two files are not present in the downloaded
|
||||
:: snapshot. Path names being too long for gitweb snapshot?
|
||||
call :DownloadFile "http://git.dev.opencascade.org/gitweb/?p=occt.git;a=blob_plain;hb=89aebdea8d6f4d15cfc50e9458cd8e2e25022326;f=src/RWStepVisual/RWStepVisual_RWCharacterizedObjectAndCharacterizedRepresentationAndDraughtingModelAndRepresentation.cxx" "%OCCT_FILENAME%\src\RWStepVisual" RWStepVisual_RWCharacterizedObjectAndCharacterizedRepresentationAndDraughtingModelAndRepresentation.cxx
|
||||
|
||||
call :DownloadFile "http://git.dev.opencascade.org/gitweb/?p=occt.git;a=blob_plain;hb=%OCCT_HASH%;f=src/RWStepVisual/RWStepVisual_RWCharacterizedObjectAndCharacterizedRepresentationAndDraughtingModelAndRepresentation.cxx" "%OCCT_FILENAME%\src\RWStepVisual" RWStepVisual_RWCharacterizedObjectAndCharacterizedRepresentationAndDraughtingModelAndRepresentation.cxx
|
||||
if not %ERRORLEVEL%==0 goto :Error
|
||||
call :DownloadFile "http://git.dev.opencascade.org/gitweb/?p=occt.git;a=blob_plain;hb=89aebdea8d6f4d15cfc50e9458cd8e2e25022326;f=src/RWStepVisual/RWStepVisual_RWCharacterizedObjectAndCharacterizedRepresentationAndDraughtingModelAndRepresentation.hxx" "%OCCT_FILENAME%\src\RWStepVisual" RWStepVisual_RWCharacterizedObjectAndCharacterizedRepresentationAndDraughtingModelAndRepresentation.hxx
|
||||
|
||||
call :DownloadFile "http://git.dev.opencascade.org/gitweb/?p=occt.git;a=blob_plain;hb=%OCCT_HASH%;f=src/RWStepVisual/RWStepVisual_RWCharacterizedObjectAndCharacterizedRepresentationAndDraughtingModelAndRepresentation.hxx" "%OCCT_FILENAME%\src\RWStepVisual" RWStepVisual_RWCharacterizedObjectAndCharacterizedRepresentationAndDraughtingModelAndRepresentation.hxx
|
||||
if not %ERRORLEVEL%==0 goto :Error
|
||||
set DEPENDENCY_NAME=Open CASCADE 7.1.0
|
||||
|
||||
if "%OCCT_VERSION%"=="7.2.0" (
|
||||
|
||||
call :DownloadFile "http://git.dev.opencascade.org/gitweb/?p=occt.git;a=blob_plain;hb=%OCCT_HASH%;f=src/StepVisual/StepVisual_AnnotationCurveOccurrenceAndAnnotationOccurrenceAndGeomReprItemAndReprItemAndStyledItem.cxx" "%OCCT_FILENAME%\src\StepVisual" StepVisual_AnnotationCurveOccurrenceAndAnnotationOccurrenceAndGeomReprItemAndReprItemAndStyledItem.cxx
|
||||
if not %ERRORLEVEL%==0 goto :Error
|
||||
|
||||
call :DownloadFile "http://git.dev.opencascade.org/gitweb/?p=occt.git;a=blob_plain;hb=%OCCT_HASH%;f=src/RWStepVisual/RWStepVisual_RWAnnotationCurveOccurrenceAndAnnotationOccurrenceAndGeomReprItemAndReprItemAndStyledItem.cxx" "%OCCT_FILENAME%\src\RWStepVisual" RWStepVisual_RWAnnotationCurveOccurrenceAndAnnotationOccurrenceAndGeomReprItemAndReprItemAndStyledItem.cxx
|
||||
if not %ERRORLEVEL%==0 goto :Error
|
||||
|
||||
call :DownloadFile "http://git.dev.opencascade.org/gitweb/?p=occt.git;a=blob_plain;hb=%OCCT_HASH%;f=src/StepVisual/StepVisual_AnnotationCurveOccurrenceAndAnnotationOccurrenceAndGeomReprItemAndReprItemAndStyledItem.hxx" "%OCCT_FILENAME%\src\StepVisual" StepVisual_AnnotationCurveOccurrenceAndAnnotationOccurrenceAndGeomReprItemAndReprItemAndStyledItem.hxx
|
||||
if not %ERRORLEVEL%==0 goto :Error
|
||||
|
||||
call :DownloadFile "http://git.dev.opencascade.org/gitweb/?p=occt.git;a=blob_plain;hb=%OCCT_HASH%;f=src/RWStepVisual/RWStepVisual_RWAnnotationCurveOccurrenceAndAnnotationOccurrenceAndGeomReprItemAndReprItemAndStyledItem.hxx" "%OCCT_FILENAME%\src\RWStepVisual" RWStepVisual_RWAnnotationCurveOccurrenceAndAnnotationOccurrenceAndGeomReprItemAndReprItemAndStyledItem.hxx
|
||||
if not %ERRORLEVEL%==0 goto :Error
|
||||
|
||||
)
|
||||
|
||||
set DEPENDENCY_NAME=Open CASCADE %OCCT_VERSION%
|
||||
|
||||
:: Patching always blindly would trigger a rebuild each time
|
||||
findstr IfcOpenShell "%DEPENDENCY_DIR%\CMakeLists.txt">NUL
|
||||
if not %ERRORLEVEL%==0 (
|
||||
echo Patching %DEPENDENCY_NAME%'s CMake files
|
||||
REM OCCT insists on finding FreeType DLL even if using static FreeType build + define HAVE_NO_DLL
|
||||
copy /y "%~dp0patches\89aebde_CMakeLists.txt" "%DEPENDENCY_DIR%\CMakeLists.txt"
|
||||
if exist "%~dp0patches\%OCCT_HASH%_CMakeLists.txt" copy /y "%~dp0patches\%OCCT_HASH%_CMakeLists.txt" "%DEPENDENCY_DIR%\CMakeLists.txt"
|
||||
REM Patch OCCT to be built against the static MSVC run-time.
|
||||
copy /y "%~dp0patches\89aebde_adm-cmake-occt_defs_flags.cmake" "%DEPENDENCY_DIR%\adm\cmake\occt_defs_flags.cmake"
|
||||
if exist "%~dp0patches\%OCCT_HASH%_adm-cmake-occt_defs_flags.cmake" copy /y "%~dp0patches\%OCCT_HASH%_adm-cmake-occt_defs_flags.cmake" "%DEPENDENCY_DIR%\adm\cmake\occt_defs_flags.cmake"
|
||||
REM OCCT tries to deploy PDBs from the bin directory even if static build is used.
|
||||
copy /y "%~dp0patches\89aebde_adm-cmake-occt_toolkit.cmake" "%DEPENDENCY_DIR%\adm\cmake\occt_toolkit.cmake"
|
||||
if exist "%~dp0patches\%OCCT_HASH%_adm-cmake-occt_toolkit.cmake" copy /y "%~dp0patches\%OCCT_HASH%_adm-cmake-occt_toolkit.cmake" "%DEPENDENCY_DIR%\adm\cmake\occt_toolkit.cmake"
|
||||
REM Patch header file for HAVE_NO_DLL
|
||||
copy /y "%~dp0patches\89aebde_Standard_Macro.hxx" "%DEPENDENCY_DIR%\src\Standard\Standard_Macro.hxx"
|
||||
if exist "%~dp0patches\%OCCT_HASH%_Standard_Macro.hxx" copy /y "%~dp0patches\%OCCT_HASH%_Standard_Macro.hxx" "%DEPENDENCY_DIR%\src\Standard\Standard_Macro.hxx"
|
||||
REM https://tracker.dev.opencascade.org/view.php?id=28248
|
||||
if exist "%~dp0patches\%OCCT_HASH%_src-HLRBRep-HLRBRep_InternalAlgo.cxx" copy /y "%~dp0patches\%OCCT_HASH%_src-HLRBRep-HLRBRep_InternalAlgo.cxx" "%DEPENDENCY_DIR%\src\HLRBRep\HLRBRep_InternalAlgo.cxx"
|
||||
REM NOTE If adding a new patch, adjust the checks above and below accordingly
|
||||
)
|
||||
findstr IfcOpenShell "%DEPENDENCY_DIR%\CMakeLists.txt">NUL
|
||||
@@ -408,7 +437,7 @@ set DEPENDENCY_NAME=SWIG %SWIG_VERSION%
|
||||
set DEPENDENCY_DIR=N/A
|
||||
set SWIG_ZIP=swigwin-%SWIG_VERSION%.zip
|
||||
cd "%DEPS_DIR%"
|
||||
call :DownloadFile http://sourceforge.net/projects/swig/files/swigwin/swigwin-%SWIG_VERSION%/%SWIG_ZIP% "%DEPS_DIR%" %SWIG_ZIP%
|
||||
call :DownloadFile https://sourceforge.net/projects/swig/files/swigwin/swigwin-%SWIG_VERSION%/%SWIG_ZIP% "%DEPS_DIR%" %SWIG_ZIP%
|
||||
IF NOT %ERRORLEVEL%==0 GOTO :Error
|
||||
call :ExtractArchive %SWIG_ZIP% "%DEPS_DIR%" "%DEPS_DIR%\swigwin"
|
||||
IF NOT %ERRORLEVEL%==0 GOTO :Error
|
||||
@@ -464,7 +493,7 @@ exit /b %IFCOS_SCRIPT_RET%
|
||||
pushd "%2"
|
||||
if not exist "%~3". (
|
||||
call cecho.cmd 0 13 "Downloading %DEPENDENCY_NAME% into %~2."
|
||||
powershell -Command "$webClient = new-object System.Net.WebClient; $webClient.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials; $webClient.DownloadFile('%1', '%3')"
|
||||
powershell -Command "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12; $webClient = new-object System.Net.WebClient; $webClient.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials; $webClient.DownloadFile('%1', '%3')"
|
||||
REM Old wget version in case someone has problem with PowerShell: wget --no-check-certificate %1
|
||||
) else (
|
||||
call cecho.cmd 0 13 "%DEPENDENCY_NAME% already downloaded. Skipping."
|
||||
@@ -478,7 +507,7 @@ exit /b %RET%
|
||||
:ExtractArchive
|
||||
if not exist "%~3". (
|
||||
call cecho.cmd 0 13 "Extracting %DEPENDENCY_NAME% into %~2."
|
||||
7za x %1 -y -o%2
|
||||
7za x %1 -y -o%2 > nul
|
||||
) else (
|
||||
call cecho.cmd 0 13 "%DEPENDENCY_NAME% already extracted into %~3. Skipping."
|
||||
)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,158 @@
|
||||
##
|
||||
|
||||
if(FLAGS_ALREADY_INCLUDED)
|
||||
return()
|
||||
endif()
|
||||
set(FLAGS_ALREADY_INCLUDED 1)
|
||||
|
||||
# force option /fp:precise for Visual Studio projects.
|
||||
#
|
||||
# Note that while this option is default for MSVC compiler, Visual Studio
|
||||
# project can be switched later to use Intel Compiler (ICC).
|
||||
# Enforcing -fp:precise ensures that in such case ICC will use correct
|
||||
# option instead of its default -fp:fast which is harmful for OCCT.
|
||||
if (MSVC)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:precise")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /fp:precise")
|
||||
endif()
|
||||
|
||||
# set compiler short name and choose SSE2 option for appropriate MSVC compilers
|
||||
# ONLY for 32-bit
|
||||
if (NOT CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
if (MSVC80 OR MSVC90 OR MSVC10)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE2")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:SSE2")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
add_definitions (-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE)
|
||||
else()
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions -fPIC")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fexceptions -fPIC")
|
||||
add_definitions(-DOCC_CONVERT_SIGNALS)
|
||||
endif()
|
||||
|
||||
# enable structured exceptions for MSVC
|
||||
string (REGEX MATCH "EHsc" ISFLAG "${CMAKE_CXX_FLAGS}")
|
||||
if (ISFLAG)
|
||||
string (REGEX REPLACE "EHsc" "EHa" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
elseif (MSVC)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHa")
|
||||
endif()
|
||||
|
||||
# remove _WINDOWS flag if it exists
|
||||
string (REGEX MATCH "/D_WINDOWS" IS_WINDOWSFLAG "${CMAKE_CXX_FLAGS}")
|
||||
if (IS_WINDOWSFLAG)
|
||||
message (STATUS "Info: /D_WINDOWS has been removed from CMAKE_CXX_FLAGS")
|
||||
string (REGEX REPLACE "/D_WINDOWS" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
endif()
|
||||
|
||||
# remove WIN32 flag if it exists
|
||||
string (REGEX MATCH "/DWIN32" IS_WIN32FLAG "${CMAKE_CXX_FLAGS}")
|
||||
if (IS_WIN32FLAG)
|
||||
message (STATUS "Info: /DWIN32 has been removed from CMAKE_CXX_FLAGS")
|
||||
string (REGEX REPLACE "/DWIN32" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
endif()
|
||||
|
||||
# remove _WINDOWS flag if it exists
|
||||
string (REGEX MATCH "/D_WINDOWS" IS_WINDOWSFLAG "${CMAKE_C_FLAGS}")
|
||||
if (IS_WINDOWSFLAG)
|
||||
message (STATUS "Info: /D_WINDOWS has been removed from CMAKE_C_FLAGS")
|
||||
string (REGEX REPLACE "/D_WINDOWS" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
endif()
|
||||
|
||||
# remove WIN32 flag if it exists
|
||||
string (REGEX MATCH "/DWIN32" IS_WIN32FLAG "${CMAKE_C_FLAGS}")
|
||||
if (IS_WIN32FLAG)
|
||||
message (STATUS "Info: /DWIN32 has been removed from CMAKE_C_FLAGS")
|
||||
string (REGEX REPLACE "/DWIN32" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
endif()
|
||||
|
||||
# remove DEBUG flag if it exists
|
||||
string (REGEX MATCH "-DDEBUG" IS_DEBUG_CXX "${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
if (IS_DEBUG_CXX)
|
||||
message (STATUS "Info: -DDEBUG has been removed from CMAKE_CXX_FLAGS_DEBUG")
|
||||
string (REGEX REPLACE "-DDEBUG" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
|
||||
endif()
|
||||
|
||||
string (REGEX MATCH "-DDEBUG" IS_DEBUG_C "${CMAKE_C_FLAGS_DEBUG}")
|
||||
if (IS_DEBUG_C)
|
||||
message (STATUS "Info: -DDEBUG has been removed from CMAKE_C_FLAGS_DEBUG")
|
||||
string (REGEX REPLACE "-DDEBUG" "" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
|
||||
endif()
|
||||
# enable parallel compilation on MSVC 9 and above
|
||||
if (MSVC AND NOT MSVC70 AND NOT MSVC80)
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")
|
||||
endif()
|
||||
|
||||
# generate a single response file which enlist all of the object files
|
||||
SET(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
SET(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1)
|
||||
# increase compiler warnings level (-W4 for MSVC, -Wextra for GCC)
|
||||
if (MSVC)
|
||||
if (CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
||||
string (REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
else()
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
||||
endif()
|
||||
elseif (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
|
||||
if (BUILD_SHARED_LIBS)
|
||||
if (APPLE)
|
||||
set (CMAKE_SHARED_LINKER_FLAGS "-lm ${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
elseif(NOT WIN32)
|
||||
set (CMAKE_SHARED_LINKER_FLAGS "-lm ${CMAKE_SHARED_LINKER_FLAGS}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(MINGW)
|
||||
# Set default release optimization option to O2 instead of O3, since in
|
||||
# some OCCT related examples, this gives significantly smaller binaries
|
||||
# at comparable performace with MinGW-w64.
|
||||
string (REGEX MATCH "-O3" IS_O3_CXX "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
if (IS_O3_CXX)
|
||||
string (REGEX REPLACE "-O3" "-O2" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
else()
|
||||
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2")
|
||||
endif()
|
||||
|
||||
set (CMAKE_CXX_FLAGS "-std=gnu++0x ${CMAKE_CXX_FLAGS}")
|
||||
add_definitions(-D_WIN32_WINNT=0x0501)
|
||||
# workaround bugs in mingw with vtable export
|
||||
set (CMAKE_SHARED_LINKER_FLAGS "-Wl,--export-all-symbols")
|
||||
elseif ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xClang")
|
||||
if (APPLE)
|
||||
# CLang can be used with both libstdc++ and libc++, however on OS X libstdc++ is outdated.
|
||||
set (CMAKE_CXX_FLAGS "-std=c++0x -stdlib=libc++ ${CMAKE_CXX_FLAGS}")
|
||||
else()
|
||||
set (CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")
|
||||
endif()
|
||||
elseif (DEFINED CMAKE_COMPILER_IS_GNUCXX)
|
||||
set (CMAKE_CXX_FLAGS "-std=c++0x ${CMAKE_CXX_FLAGS}")
|
||||
endif()
|
||||
|
||||
# Optimize size of binaries
|
||||
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX OR MINGW)
|
||||
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s")
|
||||
set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -s")
|
||||
endif()
|
||||
|
||||
set (CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNo_Exception")
|
||||
set (CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -DNo_Exception")
|
||||
|
||||
# IfcOpenShell begin
|
||||
if (MSVC)
|
||||
foreach(flag CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL
|
||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO)
|
||||
if (${flag} MATCHES "/MD")
|
||||
string(REGEX REPLACE "/MD" "/MT" ${flag} "${${flag}}")
|
||||
endif()
|
||||
if (${flag} MATCHES "/MDd")
|
||||
string(REGEX REPLACE "/MDd" "/MTd" ${flag} "${${flag}}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
# IfcOpenShell end
|
||||
@@ -0,0 +1,346 @@
|
||||
# script for each OCCT toolkit
|
||||
|
||||
# parce PACKAGES file
|
||||
if ("${PROJECT_NAME}" STREQUAL DRAWEXE)
|
||||
set (USED_PACKAGES DRAWEXE)
|
||||
else()
|
||||
FILE_TO_LIST ("src/${PROJECT_NAME}/PACKAGES" USED_PACKAGES)
|
||||
endif()
|
||||
|
||||
set (PRECOMPILED_DEFS)
|
||||
|
||||
if (NOT BUILD_SHARED_LIBS)
|
||||
list (APPEND PRECOMPILED_DEFS "-DOCCT_NO_PLUGINS")
|
||||
endif()
|
||||
|
||||
# Get all used packages from toolkit
|
||||
foreach (OCCT_PACKAGE ${USED_PACKAGES})
|
||||
|
||||
# TKService contains platform-dependent packages: Xw and WNT
|
||||
if ((WIN32 AND "${OCCT_PACKAGE}" STREQUAL "Xw") OR (NOT WIN32 AND "${OCCT_PACKAGE}" STREQUAL "WNT"))
|
||||
# do nothing
|
||||
else()
|
||||
|
||||
if (WIN32)
|
||||
list (APPEND PRECOMPILED_DEFS "-D__${OCCT_PACKAGE}_DLL")
|
||||
endif()
|
||||
|
||||
set (SOURCE_FILES)
|
||||
set (HEADER_FILES)
|
||||
|
||||
# Generate Flex and Bison files
|
||||
if (${BUILD_YACCLEX})
|
||||
|
||||
# flex files
|
||||
OCCT_ORIGIN_AND_PATCHED_FILES ("src/${OCCT_PACKAGE}" "*[.]lex" SOURCE_FILES_FLEX)
|
||||
list (LENGTH SOURCE_FILES_FLEX SOURCE_FILES_FLEX_LEN)
|
||||
|
||||
# bison files
|
||||
OCCT_ORIGIN_AND_PATCHED_FILES ("src/${OCCT_PACKAGE}" "*[.]yacc" SOURCE_FILES_BISON)
|
||||
list (LENGTH SOURCE_FILES_BISON SOURCE_FILES_BISON_LEN)
|
||||
|
||||
if (${SOURCE_FILES_FLEX_LEN} EQUAL ${SOURCE_FILES_BISON_LEN} AND NOT ${SOURCE_FILES_FLEX_LEN} EQUAL 0)
|
||||
|
||||
list (SORT SOURCE_FILES_FLEX)
|
||||
list (SORT SOURCE_FILES_BISON)
|
||||
|
||||
math (EXPR SOURCE_FILES_FLEX_LEN "${SOURCE_FILES_FLEX_LEN} - 1")
|
||||
foreach (FLEX_FILE_INDEX RANGE ${SOURCE_FILES_FLEX_LEN})
|
||||
|
||||
list (GET SOURCE_FILES_FLEX ${FLEX_FILE_INDEX} CURRENT_FLEX_FILE)
|
||||
get_filename_component (CURRENT_FLEX_FILE_NAME ${CURRENT_FLEX_FILE} NAME_WE)
|
||||
|
||||
list (GET SOURCE_FILES_BISON ${FLEX_FILE_INDEX} CURRENT_BISON_FILE)
|
||||
get_filename_component (CURRENT_BISON_FILE_NAME ${CURRENT_BISON_FILE} NAME_WE)
|
||||
|
||||
string (COMPARE EQUAL ${CURRENT_FLEX_FILE_NAME} ${CURRENT_BISON_FILE_NAME} ARE_FILES_EQUAL)
|
||||
|
||||
if (EXISTS "${CURRENT_FLEX_FILE}" AND EXISTS "${CURRENT_BISON_FILE}" AND ${ARE_FILES_EQUAL})
|
||||
set (BISON_OUTPUT_FILE ${CURRENT_BISON_FILE_NAME}.tab.c)
|
||||
set (FLEX_OUTPUT_FILE lex.${CURRENT_FLEX_FILE_NAME}.c)
|
||||
BISON_TARGET (Parser_${CURRENT_BISON_FILE_NAME} ${CURRENT_BISON_FILE} ${CMAKE_SOURCE_DIR}/src/${OCCT_PACKAGE}/${BISON_OUTPUT_FILE} COMPILE_FLAGS "-p ${CURRENT_BISON_FILE_NAME}")
|
||||
FLEX_TARGET (Scanner_${CURRENT_FLEX_FILE_NAME} ${CURRENT_FLEX_FILE} ${CMAKE_SOURCE_DIR}/src/${OCCT_PACKAGE}/${FLEX_OUTPUT_FILE} COMPILE_FLAGS "-P${CURRENT_FLEX_FILE_NAME}")
|
||||
ADD_FLEX_BISON_DEPENDENCY (Scanner_${CURRENT_FLEX_FILE_NAME} Parser_${CURRENT_BISON_FILE_NAME})
|
||||
|
||||
list (APPEND SOURCE_FILES ${BISON_OUTPUT_FILE} ${FLEX_OUTPUT_FILE})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# header files
|
||||
if (BUILD_PATCH AND EXISTS "${BUILD_PATCH}/src/${OCCT_PACKAGE}/FILES")
|
||||
file (STRINGS "${BUILD_PATCH}/src/${OCCT_PACKAGE}/FILES" HEADER_FILES_M REGEX ".+[.]h")
|
||||
file (STRINGS "${BUILD_PATCH}/src/${OCCT_PACKAGE}/FILES" HEADER_FILES_LXX REGEX ".+[.]lxx")
|
||||
file (STRINGS "${BUILD_PATCH}/src/${OCCT_PACKAGE}/FILES" HEADER_FILES_GXX REGEX ".+[.]gxx")
|
||||
|
||||
file (STRINGS "${BUILD_PATCH}/src/${OCCT_PACKAGE}/FILES" SOURCE_FILES_C REGEX ".+[.]c")
|
||||
if(APPLE)
|
||||
file (STRINGS "${BUILD_PATCH}/src/${OCCT_PACKAGE}/FILES" SOURCE_FILES_M REGEX ".+[.]mm")
|
||||
endif()
|
||||
else()
|
||||
file (STRINGS "${CMAKE_SOURCE_DIR}/src/${OCCT_PACKAGE}/FILES" HEADER_FILES_M REGEX ".+[.]h")
|
||||
file (STRINGS "${CMAKE_SOURCE_DIR}/src/${OCCT_PACKAGE}/FILES" HEADER_FILES_LXX REGEX ".+[.]lxx")
|
||||
file (STRINGS "${CMAKE_SOURCE_DIR}/src/${OCCT_PACKAGE}/FILES" HEADER_FILES_GXX REGEX ".+[.]gxx")
|
||||
|
||||
file (STRINGS "${CMAKE_SOURCE_DIR}/src/${OCCT_PACKAGE}/FILES" SOURCE_FILES_C REGEX ".+[.]c")
|
||||
if(APPLE)
|
||||
file (STRINGS "${CMAKE_SOURCE_DIR}/src/${OCCT_PACKAGE}/FILES" SOURCE_FILES_M REGEX ".+[.]mm")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
list (APPEND HEADER_FILES ${HEADER_FILES_M} ${HEADER_FILES_LXX} ${SOURCE_FILES_GXX})
|
||||
list (APPEND SOURCE_FILES ${SOURCE_FILES_C})
|
||||
if(APPLE)
|
||||
list (APPEND SOURCE_FILES ${SOURCE_FILES_M})
|
||||
endif()
|
||||
|
||||
foreach(HEADER_FILE ${HEADER_FILES})
|
||||
if (BUILD_PATCH AND EXISTS "${BUILD_PATCH}/src/${OCCT_PACKAGE}/${HEADER_FILE}")
|
||||
message (STATUS "Info: consider patched file: ${BUILD_PATCH}/src/${OCCT_PACKAGE}/${HEADER_FILE}")
|
||||
list (APPEND USED_INCFILES "${BUILD_PATCH}/src/${OCCT_PACKAGE}/${HEADER_FILE}")
|
||||
SOURCE_GROUP ("Header Files\\${OCCT_PACKAGE}" FILES "${BUILD_PATCH}/src/${OCCT_PACKAGE}/${HEADER_FILE}")
|
||||
else()
|
||||
list (APPEND USED_INCFILES "${CMAKE_SOURCE_DIR}/src/${OCCT_PACKAGE}/${HEADER_FILE}")
|
||||
SOURCE_GROUP ("Header Files\\${OCCT_PACKAGE}" FILES "${CMAKE_SOURCE_DIR}/src/${OCCT_PACKAGE}/${HEADER_FILE}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(SOURCE_FILE ${SOURCE_FILES})
|
||||
if (BUILD_PATCH AND EXISTS "${BUILD_PATCH}/src/${OCCT_PACKAGE}/${SOURCE_FILE}")
|
||||
message (STATUS "Info: consider patched file: ${BUILD_PATCH}/src/${OCCT_PACKAGE}/${SOURCE_FILE}")
|
||||
list (APPEND USED_SRCFILES "${BUILD_PATCH}/src/${OCCT_PACKAGE}/${SOURCE_FILE}")
|
||||
SOURCE_GROUP ("Source Files\\${OCCT_PACKAGE}" FILES "${BUILD_PATCH}/src/${OCCT_PACKAGE}/${SOURCE_FILE}")
|
||||
else()
|
||||
list (APPEND USED_SRCFILES "${CMAKE_SOURCE_DIR}/src/${OCCT_PACKAGE}/${SOURCE_FILE}")
|
||||
SOURCE_GROUP ("Source Files\\${OCCT_PACKAGE}" FILES "${CMAKE_SOURCE_DIR}/src/${OCCT_PACKAGE}/${SOURCE_FILE}")
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endforeach()
|
||||
string (REGEX REPLACE ";" " " PRECOMPILED_DEFS "${PRECOMPILED_DEFS}")
|
||||
|
||||
set (USED_RCFILE "")
|
||||
if (MSVC)
|
||||
set (USED_RCFILE "${CMAKE_BINARY_DIR}/resources/${PROJECT_NAME}.rc")
|
||||
|
||||
if (APPLY_OCCT_PATCH_DIR AND EXISTS "${APPLY_OCCT_PATCH_DIR}/adm/templates/occt_toolkit.rc.in")
|
||||
configure_file("${APPLY_OCCT_PATCH_DIR}/adm/templates/occt_toolkit.rc.in" "${USED_RCFILE}" @ONLY)
|
||||
else()
|
||||
configure_file("${CMAKE_SOURCE_DIR}/adm/templates/occt_toolkit.rc.in" "${USED_RCFILE}" @ONLY)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set (CURRENT_MODULE)
|
||||
foreach (OCCT_MODULE ${OCCT_MODULES})
|
||||
list (FIND ${OCCT_MODULE}_TOOLKITS ${PROJECT_NAME} CURRENT_PROJECT_IS_BUILT)
|
||||
if (NOT ${CURRENT_PROJECT_IS_BUILT} EQUAL -1)
|
||||
set (CURRENT_MODULE ${OCCT_MODULE})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if (NOT SINGLE_GENERATOR)
|
||||
OCCT_INSERT_CODE_FOR_TARGET ()
|
||||
endif()
|
||||
|
||||
if ("${PROJECT_NAME}" STREQUAL "DRAWEXE")
|
||||
add_executable (${PROJECT_NAME} ${USED_SRCFILES} ${USED_INCFILES} ${USED_RCFILE})
|
||||
|
||||
install (TARGETS ${PROJECT_NAME}
|
||||
DESTINATION "${INSTALL_DIR_BIN}\${OCCT_INSTALL_BIN_LETTER}")
|
||||
else()
|
||||
add_library (${PROJECT_NAME} ${USED_SRCFILES} ${USED_INCFILES} ${USED_RCFILE})
|
||||
|
||||
# IfcOpenShell begin
|
||||
if (BUILD_SHARED_LIBS)
|
||||
if (MSVC)
|
||||
install (FILES ${CMAKE_BINARY_DIR}/${OS_WITH_BIT}/${COMPILER}/bin\${OCCT_INSTALL_BIN_LETTER}/${PROJECT_NAME}.pdb
|
||||
CONFIGURATIONS Debug RelWithDebInfo
|
||||
DESTINATION "${INSTALL_DIR_BIN}\${OCCT_INSTALL_BIN_LETTER}")
|
||||
endif()
|
||||
else()
|
||||
if (MSVC)
|
||||
set_target_properties (${PROJECT_NAME} PROPERTIES
|
||||
COMPILE_PDB_NAME ${PROJECT_NAME}
|
||||
COMPILE_PDB_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${OS_WITH_BIT}/${COMPILER}/pdb/
|
||||
)
|
||||
|
||||
install (FILES ${CMAKE_BINARY_DIR}/${OS_WITH_BIT}/${COMPILER}/pdb/\${CMAKE_INSTALL_CONFIG_NAME}/${PROJECT_NAME}.pdb
|
||||
CONFIGURATIONS Debug RelWithDebInfo
|
||||
DESTINATION "${INSTALL_DIR_LIB}\${OCCT_INSTALL_BIN_LETTER}")
|
||||
endif()
|
||||
endif()
|
||||
# IfcOpenShell end
|
||||
|
||||
if (BUILD_SHARED_LIBS AND NOT "${BUILD_SHARED_LIBRARY_NAME_POSTFIX}" STREQUAL "")
|
||||
set (CMAKE_SHARED_LIBRARY_SUFFIX_DEFAULT ${CMAKE_SHARED_LIBRARY_SUFFIX})
|
||||
set (CMAKE_SHARED_LIBRARY_SUFFIX "${BUILD_SHARED_LIBRARY_NAME_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
endif()
|
||||
|
||||
install (TARGETS ${PROJECT_NAME}
|
||||
EXPORT OpenCASCADE${CURRENT_MODULE}Targets
|
||||
RUNTIME DESTINATION "${INSTALL_DIR_BIN}\${OCCT_INSTALL_BIN_LETTER}"
|
||||
ARCHIVE DESTINATION "${INSTALL_DIR_LIB}\${OCCT_INSTALL_BIN_LETTER}"
|
||||
LIBRARY DESTINATION "${INSTALL_DIR_LIB}\${OCCT_INSTALL_BIN_LETTER}")
|
||||
|
||||
if (NOT WIN32)
|
||||
if (BUILD_SHARED_LIBS AND NOT "${BUILD_SHARED_LIBRARY_NAME_POSTFIX}" STREQUAL "")
|
||||
set (LINK_NAME "${INSTALL_DIR}/${INSTALL_DIR_LIB}\${OCCT_INSTALL_BIN_LETTER}/lib${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX_DEFAULT}")
|
||||
set (LIBRARY_NAME "${INSTALL_DIR}/${INSTALL_DIR_LIB}\${OCCT_INSTALL_BIN_LETTER}/lib${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}")
|
||||
OCCT_CREATE_SYMLINK_TO_FILE (${LIBRARY_NAME} ${LINK_NAME})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (CURRENT_MODULE)
|
||||
set_target_properties (${PROJECT_NAME} PROPERTIES FOLDER "Modules/${CURRENT_MODULE}")
|
||||
set_target_properties (${PROJECT_NAME} PROPERTIES MODULE "${CURRENT_MODULE}")
|
||||
if (APPLE)
|
||||
if (NOT "${INSTALL_NAME_DIR}" STREQUAL "")
|
||||
set_target_properties (${PROJECT_NAME} PROPERTIES BUILD_WITH_INSTALL_RPATH 1 INSTALL_NAME_DIR "${INSTALL_NAME_DIR}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
get_property (OCC_VERSION_MAJOR GLOBAL PROPERTY OCC_VERSION_MAJOR)
|
||||
get_property (OCC_VERSION_MINOR GLOBAL PROPERTY OCC_VERSION_MINOR)
|
||||
get_property (OCC_VERSION_MAINTENANCE GLOBAL PROPERTY OCC_VERSION_MAINTENANCE)
|
||||
|
||||
if (ANDROID)
|
||||
# do not append version to the filename
|
||||
set_target_properties (${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "${PRECOMPILED_DEFS}")
|
||||
else()
|
||||
set_target_properties (${PROJECT_NAME} PROPERTIES COMPILE_FLAGS "${PRECOMPILED_DEFS}"
|
||||
SOVERSION "${OCC_VERSION_MAJOR}"
|
||||
VERSION "${OCC_VERSION_MAJOR}.${OCC_VERSION_MINOR}.${OCC_VERSION_MAINTENANCE}")
|
||||
endif()
|
||||
|
||||
set (USED_TOOLKITS_BY_CURRENT_PROJECT)
|
||||
set (USED_EXTERNAL_LIBS_BY_CURRENT_PROJECT)
|
||||
|
||||
# parce EXTERNLIB file
|
||||
FILE_TO_LIST ("src/${PROJECT_NAME}/EXTERNLIB" USED_EXTERNLIB_AND_TOOLKITS)
|
||||
foreach (USED_ITEM ${USED_EXTERNLIB_AND_TOOLKITS})
|
||||
string (REGEX MATCH "^ *#" COMMENT_FOUND ${USED_ITEM})
|
||||
if (NOT COMMENT_FOUND)
|
||||
string (REGEX MATCH "^TK" TK_FOUND ${USED_ITEM})
|
||||
string (REGEX MATCH "^vtk" VTK_FOUND ${USED_ITEM})
|
||||
|
||||
if (NOT "${TK_FOUND}" STREQUAL "" OR NOT "${VTK_FOUND}" STREQUAL "")
|
||||
list (APPEND USED_TOOLKITS_BY_CURRENT_PROJECT ${USED_ITEM})
|
||||
if (NOT "${VTK_FOUND}" STREQUAL "" AND BUILD_SHARED_LIBS AND INSTALL_VTK AND COMMAND OCCT_INSTALL_VTK)
|
||||
OCCT_INSTALL_VTK(${USED_ITEM})
|
||||
endif()
|
||||
else()
|
||||
string (REGEX MATCH "^CSF_" CSF_FOUND ${USED_ITEM})
|
||||
if ("${CSF_FOUND}" STREQUAL "")
|
||||
message (STATUS "Info: ${USED_ITEM} from ${PROJECT_NAME} skipped due to it is empty")
|
||||
else() # get CSF_ value
|
||||
set (CURRENT_CSF ${${USED_ITEM}})
|
||||
if (NOT "x${CURRENT_CSF}" STREQUAL "x")
|
||||
set (LIBRARY_FROM_CACHE 0)
|
||||
separate_arguments (CURRENT_CSF)
|
||||
foreach (CSF_LIBRARY ${CURRENT_CSF})
|
||||
string (TOLOWER "${CSF_LIBRARY}" CSF_LIBRARY)
|
||||
string (REPLACE "+" "[+]" CSF_LIBRARY "${CSF_LIBRARY}")
|
||||
string (REPLACE "." "" CSF_LIBRARY "${CSF_LIBRARY}")
|
||||
get_cmake_property(ALL_CACHE_VARIABLES CACHE_VARIABLES)
|
||||
string (REGEX MATCHALL "(^|;)3RDPARTY_[^;]+_LIBRARY[^;]*" ALL_CACHE_VARIABLES "${ALL_CACHE_VARIABLES}")
|
||||
foreach (CACHE_VARIABLE ${ALL_CACHE_VARIABLES})
|
||||
set (CURRENT_CACHE_LIBRARY ${${CACHE_VARIABLE}})
|
||||
string (TOLOWER "${CACHE_VARIABLE}" CACHE_VARIABLE)
|
||||
|
||||
if (EXISTS "${CURRENT_CACHE_LIBRARY}" AND NOT IS_DIRECTORY "${CURRENT_CACHE_LIBRARY}")
|
||||
string (REGEX MATCH "_${CSF_LIBRARY}$" IS_ENDING "${CACHE_VARIABLE}")
|
||||
string (REGEX MATCH "^([a-z]+)" CSF_WO_VERSION "${CSF_LIBRARY}")
|
||||
string (REGEX MATCH "_${CSF_WO_VERSION}$" IS_ENDING_WO_VERSION "${CACHE_VARIABLE}")
|
||||
if ("3rdparty_${CSF_LIBRARY}_library" STREQUAL "${CACHE_VARIABLE}" OR
|
||||
"3rdparty_${CSF_WO_VERSION}_library" STREQUAL "${CACHE_VARIABLE}" OR
|
||||
NOT "x${IS_ENDING}" STREQUAL "x" OR
|
||||
NOT "x${IS_ENDING_WO_VERSION}" STREQUAL "x")
|
||||
list (APPEND USED_EXTERNAL_LIBS_BY_CURRENT_PROJECT "${CURRENT_CACHE_LIBRARY}")
|
||||
set (LIBRARY_FROM_CACHE 1)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endforeach()
|
||||
|
||||
if (NOT ${LIBRARY_FROM_CACHE})
|
||||
# prepare a list from a string with whitespaces
|
||||
separate_arguments (CURRENT_CSF)
|
||||
list (APPEND USED_EXTERNAL_LIBS_BY_CURRENT_PROJECT ${CURRENT_CSF})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if (APPLE)
|
||||
list (FIND USED_EXTERNAL_LIBS_BY_CURRENT_PROJECT X11 IS_X11_FOUND)
|
||||
if (NOT ${IS_X11_FOUND} EQUAL -1)
|
||||
find_package (X11 COMPONENTS X11 Xext Xmu Xi)
|
||||
if (NOT X11_FOUND)
|
||||
message (STATUS "Warning: X11 is not found. It's required to install The XQuartz project: http://www.xquartz.org")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Update list of used VTK libraries if OpenGL2 Rendering BackEnd is used.
|
||||
# Add VTK_OPENGL2_BACKEND definition.
|
||||
if("${VTK_RENDERING_BACKEND}" STREQUAL "OpenGL2")
|
||||
add_definitions(-DVTK_OPENGL2_BACKEND)
|
||||
foreach (VTK_EXCLUDE_LIBRARY vtkRenderingOpenGL vtkRenderingFreeTypeOpenGL)
|
||||
list (FIND USED_TOOLKITS_BY_CURRENT_PROJECT "${VTK_EXCLUDE_LIBRARY}" IS_VTK_OPENGL_FOUND)
|
||||
if (NOT ${IS_VTK_OPENGL_FOUND} EQUAL -1)
|
||||
list (REMOVE_ITEM USED_TOOLKITS_BY_CURRENT_PROJECT ${VTK_EXCLUDE_LIBRARY})
|
||||
if (${VTK_EXCLUDE_LIBRARY} STREQUAL vtkRenderingOpenGL)
|
||||
list (APPEND USED_TOOLKITS_BY_CURRENT_PROJECT vtkRenderingOpenGL2)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
target_link_libraries (${PROJECT_NAME} ${USED_TOOLKITS_BY_CURRENT_PROJECT} ${USED_EXTERNAL_LIBS_BY_CURRENT_PROJECT})
|
||||
endif()
|
||||
|
||||
# suppress deprecation warnings inside OCCT itself for old gcc versions with unavailable Standard_DISABLE_DEPRECATION_WARNINGS
|
||||
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6.0)
|
||||
add_definitions("-DOCCT_NO_DEPRECATED")
|
||||
message (STATUS "Warning: internal deprecation warnings by Standard_DEPRECATED have been disabled due to old gcc version being used")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# use Cotire to accelerate build via usage of precompiled headers
|
||||
if (BUILD_USE_PCH)
|
||||
if (WIN32)
|
||||
# prevent definition of min and max macros through inclusion of Windows.h
|
||||
# (for cotire builds)
|
||||
add_definitions("-DNOMINMAX")
|
||||
# avoid warnings on deprecated names from standard C library (see strsafe.h)
|
||||
add_definitions("-DSTRSAFE_NO_DEPRECATE")
|
||||
# avoid "std::Equal1" warning in QANCollection_Stl.cxx in debug mode
|
||||
# suggesting using msvc "Checked Iterators"
|
||||
add_definitions("-D_SCL_SECURE_NO_WARNINGS")
|
||||
endif()
|
||||
|
||||
# Exclude system-provided glext.h.
|
||||
# These macros are already defined within OpenGl_GlFunctions.hxx,
|
||||
# however we have to duplicate them here for building TKOpenGl with PCH.
|
||||
add_definitions("-DGL_GLEXT_LEGACY")
|
||||
add_definitions("-DGLX_GLXEXT_LEGACY")
|
||||
|
||||
# workaround for old gcc
|
||||
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||
add_definitions("-D__STDC_CONSTANT_MACROS")
|
||||
add_definitions("-D__STDC_FORMAT_MACROS")
|
||||
endif()
|
||||
|
||||
# unity builds are not used since they do not add speed but cause conflicts
|
||||
# in TKV3d
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES COTIRE_ADD_UNITY_BUILD FALSE)
|
||||
|
||||
cotire(${PROJECT_NAME})
|
||||
endif()
|
||||
@@ -0,0 +1,938 @@
|
||||
// Created on: 1997-04-17
|
||||
// Created by: Christophe MARION
|
||||
// Copyright (c) 1997-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
|
||||
#include <HLRAlgo.hxx>
|
||||
#include <HLRAlgo_Projector.hxx>
|
||||
#include <HLRBRep_Data.hxx>
|
||||
#include <HLRBRep_Hider.hxx>
|
||||
#include <HLRBRep_InternalAlgo.hxx>
|
||||
#include <HLRBRep_ShapeBounds.hxx>
|
||||
#include <HLRBRep_ShapeToHLR.hxx>
|
||||
#include <HLRTopoBRep_OutLiner.hxx>
|
||||
#include <Standard_Transient.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <Standard_OutOfRange.hxx>
|
||||
#include <Standard_Stream.hxx>
|
||||
#include <Standard_Type.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
|
||||
#include <stdio.h>
|
||||
IMPLEMENT_STANDARD_RTTIEXT(HLRBRep_InternalAlgo,Standard_Transient)
|
||||
|
||||
extern Standard_Integer nbPtIntersection; // total P.I.
|
||||
extern Standard_Integer nbSegIntersection; // total S.I
|
||||
extern Standard_Integer nbClassification; // total classification
|
||||
extern Standard_Integer nbOkIntersection; // pairs of intersecting edges
|
||||
extern Standard_Integer nbCal1Intersection; // pairs of unrejected edges
|
||||
extern Standard_Integer nbCal2Intersection; // true intersections (not vertex)
|
||||
extern Standard_Integer nbCal3Intersection; // curve-surface intersections
|
||||
|
||||
static Standard_Integer HLRBRep_InternalAlgo_TRACE = Standard_True;
|
||||
static Standard_Integer HLRBRep_InternalAlgo_TRACE10 = Standard_True;
|
||||
|
||||
//=======================================================================
|
||||
//function : HLRBRep_InternalAlgo
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
HLRBRep_InternalAlgo::HLRBRep_InternalAlgo () :
|
||||
myDebug (Standard_False)
|
||||
{
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : HLRBRep_InternalAlgo
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
HLRBRep_InternalAlgo::
|
||||
HLRBRep_InternalAlgo (const Handle(HLRBRep_InternalAlgo)& A)
|
||||
{
|
||||
myDS = A->DataStructure();
|
||||
myProj = A->Projector();
|
||||
myShapes = A->SeqOfShapeBounds();
|
||||
myDebug = A->Debug();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Projector
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::Projector (const HLRAlgo_Projector& P)
|
||||
{
|
||||
myProj = P;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Projector
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
HLRAlgo_Projector & HLRBRep_InternalAlgo::Projector ()
|
||||
{ return myProj; }
|
||||
|
||||
//=======================================================================
|
||||
//function : Update
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::Update ()
|
||||
{
|
||||
if (!myShapes.IsEmpty()) {
|
||||
Standard_Integer n = myShapes.Length();
|
||||
Handle(HLRBRep_Data) *DS = new Handle(HLRBRep_Data) [n];
|
||||
|
||||
Standard_Integer i,dv,de,df,nv=0,ne=0,nf=0;
|
||||
|
||||
for (i = 1; i <= n; i++) {
|
||||
HLRBRep_ShapeBounds& SB = myShapes(i);
|
||||
try {
|
||||
OCC_CATCH_SIGNALS
|
||||
DS[i-1] = HLRBRep_ShapeToHLR::Load(SB.Shape(),
|
||||
myProj,
|
||||
myMapOfShapeTool,
|
||||
SB.NbOfIso());
|
||||
dv = DS[i-1]->NbVertices();
|
||||
de = DS[i-1]->NbEdges ();
|
||||
df = DS[i-1]->NbFaces ();
|
||||
}
|
||||
catch(Standard_Failure const& anException) {
|
||||
if (myDebug)
|
||||
{
|
||||
cout << "An exception was catched when preparing the Shape " << i;
|
||||
cout << " and computing its OutLines " << endl;
|
||||
cout << anException << endl;
|
||||
}
|
||||
DS[i-1] = new HLRBRep_Data(0,0,0);
|
||||
dv = 0;
|
||||
de = 0;
|
||||
df = 0;
|
||||
}
|
||||
|
||||
SB = HLRBRep_ShapeBounds
|
||||
(SB.Shape(),SB.ShapeData(),SB.NbOfIso(),1,dv,1,de,1,df);
|
||||
nv += dv;
|
||||
ne += de;
|
||||
nf += df;
|
||||
}
|
||||
|
||||
if (n == 1) myDS = DS[0];
|
||||
else {
|
||||
myDS = new HLRBRep_Data(nv,ne,nf);
|
||||
nv = 0;
|
||||
ne = 0;
|
||||
nf = 0;
|
||||
|
||||
for (i = 1; i <= n; i++) {
|
||||
HLRBRep_ShapeBounds& SB = myShapes(i);
|
||||
SB.Sizes(dv,de,df);
|
||||
SB.Translate(nv,ne,nf);
|
||||
myDS->Write(DS[i-1],nv,ne,nf);
|
||||
nv += dv;
|
||||
ne += de;
|
||||
nf += df;
|
||||
}
|
||||
}
|
||||
|
||||
delete [] DS;
|
||||
|
||||
myDS->Update(myProj);
|
||||
|
||||
HLRAlgo_EdgesBlock::MinMaxIndices ShapMin, ShapMax, MinMaxShap;
|
||||
HLRAlgo_EdgesBlock::MinMaxIndices TheMin, TheMax;
|
||||
HLRBRep_Array1OfEData& aEDataArray = myDS->EDataArray();
|
||||
HLRBRep_Array1OfFData& aFDataArray = myDS->FDataArray();
|
||||
|
||||
for (i = 1; i <= n; i++) {
|
||||
Standard_Boolean FirstTime = Standard_True;
|
||||
HLRBRep_ShapeBounds& SB = myShapes(i);
|
||||
Standard_Integer v1,v2,e1,e2,f1,f2;
|
||||
SB.Bounds(v1,v2,e1,e2,f1,f2);
|
||||
|
||||
for (Standard_Integer e = e1; e <= e2; e++) {
|
||||
HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(e);
|
||||
HLRAlgo::DecodeMinMax(ed.MinMax(), TheMin, TheMax);
|
||||
if (FirstTime) {
|
||||
FirstTime = Standard_False;
|
||||
HLRAlgo::CopyMinMax(TheMin, TheMax, ShapMin, ShapMax);
|
||||
}
|
||||
else
|
||||
HLRAlgo::AddMinMax(TheMin, TheMax, ShapMin, ShapMax);
|
||||
}
|
||||
|
||||
for (Standard_Integer f = f1; f <= f2; f++) {
|
||||
HLRBRep_FaceData& fd = aFDataArray.ChangeValue(f);
|
||||
HLRAlgo::DecodeMinMax(fd.Wires()->MinMax(), TheMin, TheMax);
|
||||
HLRAlgo::AddMinMax(TheMin, TheMax, ShapMin, ShapMax);
|
||||
}
|
||||
HLRAlgo::EncodeMinMax(ShapMin, ShapMax, MinMaxShap);
|
||||
SB.UpdateMinMax(MinMaxShap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Load
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::Load (const Handle(HLRTopoBRep_OutLiner)& S,
|
||||
const Handle(Standard_Transient)& SData,
|
||||
const Standard_Integer nbIso)
|
||||
{
|
||||
myShapes.Append(HLRBRep_ShapeBounds(S,SData,nbIso,0,0,0,0,0,0));
|
||||
myDS.Nullify();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Load
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::Load (const Handle(HLRTopoBRep_OutLiner)& S,
|
||||
const Standard_Integer nbIso)
|
||||
{
|
||||
myShapes.Append(HLRBRep_ShapeBounds(S,nbIso,0,0,0,0,0,0));
|
||||
myDS.Nullify();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Index
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer HLRBRep_InternalAlgo::
|
||||
Index (const Handle(HLRTopoBRep_OutLiner)& S) const
|
||||
{
|
||||
Standard_Integer n = myShapes.Length();
|
||||
|
||||
for (Standard_Integer i = 1; i <= n; i++)
|
||||
if (myShapes(i).Shape() == S) return i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Remove
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::Remove (const Standard_Integer I)
|
||||
{
|
||||
Standard_OutOfRange_Raise_if
|
||||
(I == 0 || I > myShapes.Length(),
|
||||
"HLRBRep_InternalAlgo::Remove : unknown Shape");
|
||||
myShapes.Remove(I);
|
||||
|
||||
myMapOfShapeTool.Clear();
|
||||
myDS.Nullify();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeData
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::ShapeData (const Standard_Integer I,
|
||||
const Handle(Standard_Transient)& SData)
|
||||
{
|
||||
Standard_OutOfRange_Raise_if
|
||||
(I == 0 || I > myShapes.Length(),
|
||||
"HLRBRep_InternalAlgo::ShapeData : unknown Shape");
|
||||
|
||||
myShapes(I).ShapeData(SData);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SeqOfShapeBounds
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
HLRBRep_SeqOfShapeBounds & HLRBRep_InternalAlgo::SeqOfShapeBounds ()
|
||||
{
|
||||
return myShapes;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : NbShapes
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Integer HLRBRep_InternalAlgo::NbShapes () const
|
||||
{ return myShapes.Length(); }
|
||||
|
||||
//=======================================================================
|
||||
//function : ShapeBounds
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
HLRBRep_ShapeBounds & HLRBRep_InternalAlgo::
|
||||
ShapeBounds (const Standard_Integer I)
|
||||
{
|
||||
Standard_OutOfRange_Raise_if
|
||||
(I == 0 || I > myShapes.Length(),
|
||||
"HLRBRep_InternalAlgo::ShapeBounds : unknown Shape");
|
||||
|
||||
return myShapes(I);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : InitEdgeStatus
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::InitEdgeStatus ()
|
||||
{
|
||||
Standard_Boolean visible;
|
||||
HLRBRep_FaceIterator faceIt;
|
||||
|
||||
HLRBRep_Array1OfEData& aEDataArray = myDS->EDataArray();
|
||||
HLRBRep_Array1OfFData& aFDataArray = myDS->FDataArray();
|
||||
Standard_Integer ne = myDS->NbEdges();
|
||||
Standard_Integer nf = myDS->NbFaces();
|
||||
|
||||
for (Standard_Integer e = 1; e <= ne; e++) {
|
||||
HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(e);
|
||||
if (ed.Selected()) ed.Status().ShowAll();
|
||||
}
|
||||
// for (Standard_Integer f = 1; f <= nf; f++) {
|
||||
Standard_Integer f;
|
||||
for ( f = 1; f <= nf; f++) {
|
||||
HLRBRep_FaceData& fd = aFDataArray.ChangeValue(f);
|
||||
if (fd.Selected()) {
|
||||
|
||||
for (faceIt.InitEdge(fd);
|
||||
faceIt.MoreEdge();
|
||||
faceIt.NextEdge()) {
|
||||
HLRBRep_EdgeData* edf = &(myDS->EDataArray().ChangeValue(faceIt.Edge()));
|
||||
if (edf->Selected()) edf->Status().HideAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (f = 1; f <= nf; f++) {
|
||||
HLRBRep_FaceData& fd = aFDataArray.ChangeValue(f);
|
||||
visible = Standard_True;
|
||||
if (fd.Selected() && fd.Closed()) {
|
||||
if ( fd.Side()) visible = Standard_False;
|
||||
else if ( !fd.WithOutL()) {
|
||||
switch (fd.Orientation()) {
|
||||
case TopAbs_REVERSED : visible = fd.Back() ; break;
|
||||
case TopAbs_FORWARD : visible = !fd.Back() ; break;
|
||||
case TopAbs_EXTERNAL :
|
||||
case TopAbs_INTERNAL : visible = Standard_True; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (visible) {
|
||||
|
||||
for (faceIt.InitEdge(fd);
|
||||
faceIt.MoreEdge();
|
||||
faceIt.NextEdge()) {
|
||||
Standard_Integer E = faceIt.Edge();
|
||||
HLRBRep_EdgeData* edf = &(myDS->EDataArray().ChangeValue(E));
|
||||
if ( edf->Selected() &&
|
||||
!edf->Vertical())
|
||||
edf->Status().ShowAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Select
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::Select ()
|
||||
{
|
||||
if (!myDS.IsNull()) {
|
||||
HLRBRep_Array1OfEData& aEDataArray = myDS->EDataArray();
|
||||
HLRBRep_Array1OfFData& aFDataArray = myDS->FDataArray();
|
||||
Standard_Integer ne = myDS->NbEdges();
|
||||
Standard_Integer nf = myDS->NbFaces();
|
||||
|
||||
for (Standard_Integer e = 1; e <= ne; e++) {
|
||||
HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(e);
|
||||
ed.Selected(Standard_True);
|
||||
}
|
||||
|
||||
for (Standard_Integer f = 1; f <= nf; f++) {
|
||||
HLRBRep_FaceData& fd = aFDataArray.ChangeValue(f);
|
||||
fd.Selected(Standard_True);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Select
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::Select (const Standard_Integer I)
|
||||
{
|
||||
if (!myDS.IsNull()) {
|
||||
Standard_OutOfRange_Raise_if
|
||||
(I == 0 || I > myShapes.Length(),
|
||||
"HLRBRep_InternalAlgo::Select : unknown Shape");
|
||||
|
||||
Standard_Integer v1,v2,e1,e2,f1,f2;
|
||||
myShapes(I).Bounds(v1,v2,e1,e2,f1,f2);
|
||||
|
||||
HLRBRep_Array1OfEData& aEDataArray = myDS->EDataArray();
|
||||
HLRBRep_Array1OfFData& aFDataArray = myDS->FDataArray();
|
||||
Standard_Integer ne = myDS->NbEdges();
|
||||
Standard_Integer nf = myDS->NbFaces();
|
||||
|
||||
for (Standard_Integer e = 1; e <= ne; e++) {
|
||||
HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(e);
|
||||
ed.Selected(e >= e1 && e <= e2);
|
||||
}
|
||||
|
||||
for (Standard_Integer f = 1; f <= nf; f++) {
|
||||
HLRBRep_FaceData& fd = aFDataArray.ChangeValue(f);
|
||||
fd.Selected(f >= f1 && f <= f2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SelectEdge
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::SelectEdge (const Standard_Integer I)
|
||||
{
|
||||
if (!myDS.IsNull()) {
|
||||
Standard_OutOfRange_Raise_if
|
||||
(I == 0 || I > myShapes.Length(),
|
||||
"HLRBRep_InternalAlgo::SelectEdge : unknown Shape");
|
||||
|
||||
Standard_Integer v1,v2,e1,e2,f1,f2;
|
||||
myShapes(I).Bounds(v1,v2,e1,e2,f1,f2);
|
||||
|
||||
HLRBRep_Array1OfEData& aEDataArray = myDS->EDataArray();
|
||||
Standard_Integer ne = myDS->NbEdges();
|
||||
|
||||
for (Standard_Integer e = 1; e <= ne; e++) {
|
||||
HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(e);
|
||||
ed.Selected(e >= e1 && e <= e2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SelectFace
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::SelectFace (const Standard_Integer I)
|
||||
{
|
||||
if (!myDS.IsNull()) {
|
||||
Standard_OutOfRange_Raise_if
|
||||
(I == 0 || I > myShapes.Length(),
|
||||
"HLRBRep_InternalAlgo::SelectFace : unknown Shape");
|
||||
|
||||
Standard_Integer v1,v2,e1,e2,f1,f2;
|
||||
myShapes(I).Bounds(v1,v2,e1,e2,f1,f2);
|
||||
|
||||
HLRBRep_Array1OfFData& aFDataArray = myDS->FDataArray();
|
||||
Standard_Integer nf = myDS->NbFaces();
|
||||
|
||||
for (Standard_Integer f = 1; f <= nf; f++) {
|
||||
HLRBRep_FaceData& fd = aFDataArray.ChangeValue(f);
|
||||
fd.Selected(f >= f1 && f <= f2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ShowAll
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::ShowAll ()
|
||||
{
|
||||
if (!myDS.IsNull()) {
|
||||
HLRBRep_Array1OfEData& aEDataArray = myDS->EDataArray();
|
||||
Standard_Integer ne = myDS->NbEdges();
|
||||
|
||||
for (Standard_Integer ie = 1; ie <= ne; ie++) {
|
||||
HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(ie);
|
||||
ed.Status().ShowAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : ShowAll
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::ShowAll (const Standard_Integer I)
|
||||
{
|
||||
if (!myDS.IsNull()) {
|
||||
Standard_OutOfRange_Raise_if
|
||||
(I == 0 || I > myShapes.Length(),
|
||||
"HLRBRep_InternalAlgo::ShowAll : unknown Shape");
|
||||
|
||||
Select(I);
|
||||
|
||||
HLRBRep_Array1OfEData& aEDataArray = myDS->EDataArray();
|
||||
Standard_Integer ne = myDS->NbEdges();
|
||||
|
||||
for (Standard_Integer e = 1; e <= ne; e++) {
|
||||
HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(e);
|
||||
if (ed.Selected()) ed.Status().ShowAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : HideAll
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::HideAll ()
|
||||
{
|
||||
if (!myDS.IsNull()) {
|
||||
HLRBRep_Array1OfEData& aEDataArray = myDS->EDataArray();
|
||||
Standard_Integer ne = myDS->NbEdges();
|
||||
|
||||
for (Standard_Integer ie = 1; ie <= ne; ie++) {
|
||||
HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(ie);
|
||||
ed.Status().HideAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : HideAll
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::HideAll (const Standard_Integer I)
|
||||
{
|
||||
if (!myDS.IsNull()) {
|
||||
Standard_OutOfRange_Raise_if
|
||||
(I == 0 || I > myShapes.Length(),
|
||||
"HLRBRep_InternalAlgo::HideAll : unknown Shape");
|
||||
|
||||
Select(I);
|
||||
|
||||
HLRBRep_Array1OfEData& aEDataArray = myDS->EDataArray();
|
||||
Standard_Integer ne = myDS->NbEdges();
|
||||
|
||||
for (Standard_Integer e = 1; e <= ne; e++) {
|
||||
HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(e);
|
||||
if (ed.Selected()) ed.Status().HideAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : PartialHide
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::PartialHide ()
|
||||
{
|
||||
if (!myDS.IsNull()) {
|
||||
Standard_Integer i,n = myShapes.Length();
|
||||
|
||||
if (myDebug)
|
||||
cout << " Partial hiding" << endl << endl;
|
||||
|
||||
for (i = 1; i <= n; i++)
|
||||
Hide(i);
|
||||
|
||||
Select();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Hide
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::Hide ()
|
||||
{
|
||||
if (!myDS.IsNull()) {
|
||||
Standard_Integer i,j,n = myShapes.Length();
|
||||
|
||||
if (myDebug)
|
||||
cout << " Total hiding" << endl;
|
||||
|
||||
for (i = 1; i <= n; i++)
|
||||
Hide(i);
|
||||
|
||||
for (i = 1; i <= n; i++)
|
||||
for (j = 1; j <= n; j++)
|
||||
if (i != j) Hide(i,j);
|
||||
|
||||
Select();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Hide
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::Hide (const Standard_Integer I)
|
||||
{
|
||||
if (!myDS.IsNull()) {
|
||||
Standard_OutOfRange_Raise_if
|
||||
(I == 0 || I > myShapes.Length(),
|
||||
"HLRBRep_InternalAlgo::Hide : unknown Shape");
|
||||
|
||||
if (myDebug)
|
||||
cout << " hiding the shape " << I << " by itself" << endl;
|
||||
|
||||
Select(I);
|
||||
InitEdgeStatus();
|
||||
HideSelected(I,Standard_True);
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Hide
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::Hide (const Standard_Integer I,
|
||||
const Standard_Integer J)
|
||||
{
|
||||
if (!myDS.IsNull()) {
|
||||
Standard_OutOfRange_Raise_if
|
||||
(I == 0 || I > myShapes.Length() ||
|
||||
J == 0 || J > myShapes.Length(),
|
||||
"HLRBRep_InternalAlgo::Hide : unknown Shapes");
|
||||
|
||||
if (I == J) Hide(I);
|
||||
else {
|
||||
HLRAlgo_EdgesBlock::MinMaxIndices* MinMaxShBI = &myShapes(I).MinMax();
|
||||
HLRAlgo_EdgesBlock::MinMaxIndices* MinMaxShBJ = &myShapes(J).MinMax();
|
||||
if (((MinMaxShBJ->Max[0] - MinMaxShBI->Min[0]) & 0x80008000) == 0 &&
|
||||
((MinMaxShBI->Max[0] - MinMaxShBJ->Min[0]) & 0x80008000) == 0 &&
|
||||
((MinMaxShBJ->Max[1] - MinMaxShBI->Min[1]) & 0x80008000) == 0 &&
|
||||
((MinMaxShBI->Max[1] - MinMaxShBJ->Min[1]) & 0x80008000) == 0 &&
|
||||
((MinMaxShBJ->Max[2] - MinMaxShBI->Min[2]) & 0x80008000) == 0 &&
|
||||
((MinMaxShBI->Max[2] - MinMaxShBJ->Min[2]) & 0x80008000) == 0 &&
|
||||
((MinMaxShBJ->Max[3] - MinMaxShBI->Min[3]) & 0x80008000) == 0 &&
|
||||
((MinMaxShBI->Max[3] - MinMaxShBJ->Min[3]) & 0x80008000) == 0 &&
|
||||
((MinMaxShBJ->Max[4] - MinMaxShBI->Min[4]) & 0x80008000) == 0 &&
|
||||
((MinMaxShBI->Max[4] - MinMaxShBJ->Min[4]) & 0x80008000) == 0 &&
|
||||
((MinMaxShBJ->Max[5] - MinMaxShBI->Min[5]) & 0x80008000) == 0 &&
|
||||
((MinMaxShBI->Max[5] - MinMaxShBJ->Min[5]) & 0x80008000) == 0 &&
|
||||
((MinMaxShBJ->Max[6] - MinMaxShBI->Min[6]) & 0x80008000) == 0 &&
|
||||
((MinMaxShBJ->Max[7] - MinMaxShBI->Min[7]) & 0x80008000) == 0) {
|
||||
if (myDebug) {
|
||||
cout << " hiding the shape " << I;
|
||||
cout << " by the shape : " << J << endl;
|
||||
}
|
||||
SelectEdge(I);
|
||||
SelectFace(J);
|
||||
HideSelected(I,Standard_False);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : HideSelected
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::HideSelected (const Standard_Integer I,
|
||||
const Standard_Boolean SideFace)
|
||||
{
|
||||
Standard_Integer e,f,j,nbVisEdges,nbSelEdges,nbSelFaces,nbCache;
|
||||
Standard_Integer nbFSide,nbFSimp;
|
||||
|
||||
#ifdef OCCT_DEBUG
|
||||
if (myDebug) {
|
||||
nbPtIntersection = 0;
|
||||
nbSegIntersection = 0;
|
||||
nbOkIntersection = 0;
|
||||
nbClassification = 0;
|
||||
nbCal1Intersection = 0;
|
||||
nbCal2Intersection = 0;
|
||||
nbCal3Intersection = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
HLRBRep_ShapeBounds& SB = myShapes(I);
|
||||
Standard_Integer v1,v2,e1,e2,f1,f2;
|
||||
SB.Bounds(v1,v2,e1,e2,f1,f2);
|
||||
|
||||
if (e2 >= e1) {
|
||||
myDS->InitBoundSort(SB.MinMax(),e1,e2);
|
||||
HLRBRep_Hider Cache(myDS);
|
||||
HLRBRep_Array1OfEData& aEDataArray = myDS->EDataArray();
|
||||
HLRBRep_Array1OfFData& aFDataArray = myDS->FDataArray();
|
||||
Standard_Integer ne = myDS->NbEdges();
|
||||
Standard_Integer nf = myDS->NbFaces();
|
||||
|
||||
if (myDebug) {
|
||||
nbVisEdges = 0;
|
||||
nbSelEdges = 0;
|
||||
nbSelFaces = 0;
|
||||
nbCache = 0;
|
||||
nbFSide = 0;
|
||||
nbFSimp = 0;
|
||||
|
||||
for (e = 1; e <= ne; e++) {
|
||||
HLRBRep_EdgeData& ed = aEDataArray.ChangeValue(e);
|
||||
if (ed.Selected()) {
|
||||
nbSelEdges++;
|
||||
if (!ed.Status().AllHidden()) nbVisEdges++;
|
||||
}
|
||||
}
|
||||
|
||||
for (f = 1; f <= nf; f++) {
|
||||
HLRBRep_FaceData& fd = aFDataArray.ChangeValue(f);
|
||||
if (fd.Selected()) {
|
||||
nbSelFaces++;
|
||||
if (fd.Hiding()) nbCache++;
|
||||
if (fd.Side ()) nbFSide++;
|
||||
if (fd.Simple()) nbFSimp++;
|
||||
}
|
||||
}
|
||||
|
||||
if (myDebug)
|
||||
{
|
||||
cout << endl;
|
||||
cout << "Vertices : " << setw(5) << myDS->NbVertices() << endl;
|
||||
cout << "Edges : " << setw(5) << myDS->NbEdges() << " , ";
|
||||
cout << "Selected : " << setw(5) << nbSelEdges << " , ";
|
||||
cout << "Visibles : " << setw(5) << nbVisEdges << endl;
|
||||
cout << "Faces : " << setw(5) << myDS->NbFaces() << " , ";
|
||||
cout << "Selected : " << setw(5) << nbSelFaces << " , ";
|
||||
cout << "Simple : " << setw(5) << nbFSimp << endl;
|
||||
if (SideFace)
|
||||
cout << "Side : " << setw(5) << nbFSide << " , ";
|
||||
cout << "Cachantes : " << setw(5) << nbCache << endl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (nf == 0)
|
||||
return;
|
||||
|
||||
Standard_Integer QWE=0,QWEQWE;
|
||||
QWEQWE=nf/10;
|
||||
|
||||
if (SideFace) {
|
||||
j = 0;
|
||||
|
||||
for (f = 1; f <= nf; f++) {
|
||||
HLRBRep_FaceData& fd = aFDataArray.ChangeValue(f);
|
||||
if (fd.Selected()) {
|
||||
if (fd.Side()) {
|
||||
if(HLRBRep_InternalAlgo_TRACE10) {
|
||||
if(++QWE>QWEQWE) {
|
||||
QWE=0;
|
||||
if (myDebug)
|
||||
cout<<"*";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (myDebug && HLRBRep_InternalAlgo_TRACE) {
|
||||
j++;
|
||||
cout << " OwnHiding " << j << " of face : " << f << endl;
|
||||
}
|
||||
}
|
||||
Cache.OwnHiding(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--
|
||||
TColStd_Array1OfInteger Val(1, nf);
|
||||
TColStd_Array1OfReal Size(1, nf);
|
||||
TColStd_Array1OfInteger Index(1, nf);
|
||||
|
||||
|
||||
for (f = 1; f <= nf; f++) {
|
||||
HLRBRep_FaceData& fd = aFDataArray.ChangeValue(f);
|
||||
if (fd.Plane()) Val(f) = 10;
|
||||
else if(fd.Cylinder()) Val(f)=9;
|
||||
else if(fd.Cone()) Val(f)=8;
|
||||
else if(fd.Sphere()) Val(f)=7;
|
||||
else if(fd.Torus()) Val(f)=6;
|
||||
else Val(f)=0;
|
||||
if(fd.Cut()) Val(f)-=10;
|
||||
if(fd.Side()) Val(f)-=100;
|
||||
if(fd.WithOutL()) Val(f)-=20;
|
||||
|
||||
Size(f)=fd.Size();
|
||||
}
|
||||
|
||||
for(Standard_Integer tt=1;tt<=nf;tt++) {
|
||||
Index(tt)=tt;
|
||||
}
|
||||
|
||||
//-- ======================================================================
|
||||
/* Standard_Boolean TriOk; //-- a refaire
|
||||
do {
|
||||
Standard_Integer t,tp1;
|
||||
TriOk=Standard_True;
|
||||
for(t=1,tp1=2;t<nf;t++,tp1++) {
|
||||
if(Val(Index(t))<Val(Index(tp1))) {
|
||||
Standard_Integer q=Index(t); Index(t)=Index(tp1); Index(tp1)=q;
|
||||
TriOk=Standard_False;
|
||||
}
|
||||
else if(Val(Index(t))==Val(Index(tp1))) {
|
||||
if(Size(Index(t))<Size(Index(tp1))) {
|
||||
Standard_Integer q=Index(t); Index(t)=Index(tp1); Index(tp1)=q;
|
||||
TriOk=Standard_False;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while(TriOk==Standard_False);
|
||||
*/
|
||||
//-- ======================================================================
|
||||
if(nf>2) {
|
||||
Standard_Integer i,ir,k,l;
|
||||
Standard_Integer rra;
|
||||
l=(nf>>1)+1;
|
||||
ir=nf;
|
||||
for(;;) {
|
||||
if(l>1) {
|
||||
rra=Index(--l);
|
||||
}
|
||||
else {
|
||||
rra=Index(ir);
|
||||
Index(ir)=Index(1);
|
||||
if(--ir == 1) {
|
||||
Index(1)=rra;
|
||||
break;
|
||||
}
|
||||
}
|
||||
i=l;
|
||||
k=l+l;
|
||||
while(k<=ir) {
|
||||
if(k<ir) {
|
||||
if(Val(Index(k)) > Val(Index(k+1)))
|
||||
k++;
|
||||
else if(Val(Index(k)) == Val(Index(k+1))) {
|
||||
if(Size(Index(k)) > Size(Index(k+1)))
|
||||
k++;
|
||||
}
|
||||
}
|
||||
if(Val(rra) > Val(Index(k))) {
|
||||
Index(i)=Index(k);
|
||||
i=k;
|
||||
k<<=1;
|
||||
}
|
||||
else if((Val(rra) == Val(Index(k))) && (Size(rra) > Size(Index(k)))) {
|
||||
Index(i)=Index(k);
|
||||
i=k;
|
||||
k<<=1;
|
||||
}
|
||||
else {
|
||||
k=ir+1;
|
||||
}
|
||||
}
|
||||
Index(i)=rra;
|
||||
}
|
||||
}
|
||||
|
||||
j = 0;
|
||||
|
||||
QWE=0;
|
||||
for (f = 1; f <= nf; f++) {
|
||||
Standard_Integer fi = Index(f);
|
||||
HLRBRep_FaceData& fd = aFDataArray.ChangeValue(fi);
|
||||
if (fd.Selected()) {
|
||||
if (fd.Hiding()) {
|
||||
if(HLRBRep_InternalAlgo_TRACE10 && HLRBRep_InternalAlgo_TRACE==Standard_False) {
|
||||
if(++QWE>QWEQWE) {
|
||||
if (myDebug)
|
||||
cout<<".";
|
||||
QWE=0;
|
||||
}
|
||||
}
|
||||
else if (myDebug && HLRBRep_InternalAlgo_TRACE) {
|
||||
static int rty=0;
|
||||
j++;
|
||||
printf("%6d",fi); fflush(stdout);
|
||||
if(++rty>25) { rty=0; printf("\n"); }
|
||||
}
|
||||
Cache.Hide(fi,myMapOfShapeTool);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef OCCT_DEBUG
|
||||
if (myDebug) {
|
||||
nbFSimp = 0;
|
||||
|
||||
for (f = 1; f <= nf; f++) {
|
||||
HLRBRep_FaceData& fd = aFDataArray.ChangeValue(f);
|
||||
if (fd.Selected() && fd.Simple())
|
||||
nbFSimp++;
|
||||
}
|
||||
|
||||
cout << "\n";
|
||||
cout << "Simple Faces : ";
|
||||
cout << nbFSimp << "\n";
|
||||
cout << "Intersections calculees : ";
|
||||
cout << nbCal2Intersection << "\n";
|
||||
cout << "Intersections Ok : ";
|
||||
cout << nbOkIntersection << "\n";
|
||||
cout << "Points : ";
|
||||
cout << nbPtIntersection << "\n";
|
||||
cout << "Segments : ";
|
||||
cout << nbSegIntersection << "\n";
|
||||
cout << "Classification : ";
|
||||
cout << nbClassification << "\n";
|
||||
cout << "Intersections curve-surface : ";
|
||||
cout << nbCal3Intersection << "\n";
|
||||
cout << endl << endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Debug
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
void HLRBRep_InternalAlgo::Debug (const Standard_Boolean deb)
|
||||
{ myDebug = deb; }
|
||||
|
||||
//=======================================================================
|
||||
//function : Debug
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean HLRBRep_InternalAlgo::Debug () const
|
||||
{ return myDebug; }
|
||||
|
||||
//=======================================================================
|
||||
//function : DataStructure
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Handle(HLRBRep_Data) HLRBRep_InternalAlgo::DataStructure () const
|
||||
{ return myDS; }
|
||||
+6
-3
@@ -58,9 +58,12 @@ popd
|
||||
IF NOT EXIST ..\%BUILD_DIR%. mkdir ..\%BUILD_DIR%
|
||||
pushd ..\%BUILD_DIR%
|
||||
|
||||
set BOOST_ROOT=%DEPS_DIR%\boost
|
||||
REM set BOOST_INCLUDEDIR=%DEPS_DIR%\boost\boost
|
||||
set BOOST_LIBRARYDIR=%DEPS_DIR%\boost\stage\vs%VS_VER%-%VS_PLATFORM%\lib
|
||||
:: tfk: todo remove duplication
|
||||
set BOOST_VERSION=1.67.0
|
||||
set BOOST_VER=%BOOST_VERSION:.=_%
|
||||
|
||||
set BOOST_ROOT=%DEPS_DIR%\boost_%BOOST_VER%
|
||||
set BOOST_LIBRARYDIR=%BOOST_ROOT%\stage\vs%VS_VER%-%VS_PLATFORM%\lib
|
||||
set ICU_INCLUDE_DIR=%INSTALL_DIR%\icu\include
|
||||
set ICU_LIBRARY_DIR=%INSTALL_DIR%\icu\lib
|
||||
if not defined OCC_INCLUDE_DIR set OCC_INCLUDE_DIR=%INSTALL_DIR%\oce\include\oce
|
||||
|
||||
Reference in New Issue
Block a user