Files
IfcOpenShell/src/ifcviewer/Placement.h
T
Dion Moult f7add7f412 ifcviewer: auto-guess FederatedFalseOrigin on first model added
When the user adds a model into a fresh, untitled federation that still
has the default (0,0,0, no rotation) FederatedFalseOrigin, derive an
origin from the first instance's placement_transformation (lifted
through CoordinateOperation when enabled) and the helmert grid-north
baked into ModelGeoref::coordinate_operation_meters.  Multi-file batches
naturally settle: whichever load finishes first anchors the federation,
the rest see a non-default origin and skip.  Saved .ifcfeds keep their
authoritative origin.

Adds Placement.{h,cpp} (port of util/placement.py — a2p,
get_axis2placement, get_local_placement) so Geolocation no longer needs
its own anonymous getAxis2Placement, and xaxis2angleDeg in Geolocation
mirroring util/geolocation.xaxis2angle.

SceneLoader captures the first instance's placement_transformation from
either the sidecar's InstanceCpu[0] or the streamer's first
InstanceChunk, so the guess works on both load paths without re-reading
the IFC.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-03 10:04:39 +10:00

51 lines
2.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/********************************************************************************
* *
* This file is part of IfcOpenShell. *
* *
* IfcOpenShell is free software: you can redistribute it and/or modify *
* it under the terms of the Lesser GNU General Public License as published by *
* the Free Software Foundation, either version 3.0 of the License, or *
* (at your option) any later version. *
* *
* IfcOpenShell is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* Lesser GNU General Public License for more details. *
* *
* You should have received a copy of the Lesser GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
* *
********************************************************************************/
// Port of selected helpers from
// src/ifcopenshell-python/ifcopenshell/util/placement.py — entity-instance
// placement chains -> 4x4 matrices, used by callers that need to read
// IfcLocalPlacement / IfcAxis2Placement* outside of the geometry kernel.
#ifndef PLACEMENT_H
#define PLACEMENT_H
#include "../ifcparse/express.h"
#include <Eigen/Dense>
// Build a 4x4 placement matrix from an origin + Z + X axis triple, mirroring
// ifcopenshell.util.placement.a2p. The Y axis is derived as Z × X. Inputs
// don't need to be unit; vectors are renormalised internally.
Eigen::Matrix4d a2p(const Eigen::Vector3d& origin,
const Eigen::Vector3d& z,
const Eigen::Vector3d& x);
// IfcAxis2Placement{2D,3D,Linear} / IfcAxis1Placement -> 4x4 matrix. Mirrors
// ifcopenshell.util.placement.get_axis2placement. Returns identity for null
// or unparseable inputs. Translation is in the IFC's project length unit.
Eigen::Matrix4d getAxis2Placement(const express::Base& placement);
// Resolve an IfcLocalPlacement (or an IfcAxis2Placement* directly) into a
// 4x4 matrix in the IFC project's length unit, walking the PlacementRelTo
// chain. Mirrors ifcopenshell.util.placement.get_local_placement. Returns
// identity for a null input.
Eigen::Matrix4d getLocalPlacement(const express::Base& placement);
#endif // PLACEMENT_H