parent
71eb1c2b41
commit
35d30e18af
@ -1,6 +1,6 @@ |
||||
module OpenProject::Bcf |
||||
module BcfJson |
||||
class ViewpointMapper |
||||
class ViewpointReader |
||||
ROOT_NODE ||= 'VisualizationInfo'.freeze |
||||
|
||||
attr_reader :uuid, :xml |
@ -0,0 +1,67 @@ |
||||
## |
||||
# Creates or updates a BCF issue and markup from a work package |
||||
module OpenProject::Bcf::BcfXml |
||||
class BaseWriter |
||||
attr_reader :markup_doc |
||||
|
||||
def initialize |
||||
@markup_doc = build_markup_document |
||||
end |
||||
|
||||
protected |
||||
|
||||
def root_node |
||||
raise NotImplementedError |
||||
end |
||||
|
||||
def root_node_attributes |
||||
{} |
||||
end |
||||
|
||||
## |
||||
# Initial markup file as basic BCF compliant xml |
||||
def build_markup_document |
||||
Nokogiri::XML::Builder |
||||
.new(:encoding => 'UTF-8') do |xml| |
||||
xml.comment created_by_comment |
||||
xml.send(root_node, |
||||
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance", |
||||
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema", |
||||
**root_node_attributes) |
||||
end |
||||
.doc |
||||
end |
||||
|
||||
def prepend_into_or_insert(parent_node, node) |
||||
if first_child = parent_node.children.select(&:element?)&.first |
||||
first_child.previous = node |
||||
else |
||||
node.parent = parent_node |
||||
end |
||||
end |
||||
|
||||
def fetch(parent_node, name) |
||||
node = parent_node.at(name) || Nokogiri::XML::Node.new(name, markup_doc) |
||||
node.parent = parent_node unless node.parent.present? |
||||
node |
||||
end |
||||
|
||||
## |
||||
# |
||||
def created_by_comment |
||||
" Created by #{Setting.app_title} #{OpenProject::VERSION} at #{Time.now} " |
||||
end |
||||
|
||||
def to_bcf_datetime(date_time) |
||||
date_time.utc.iso8601 |
||||
end |
||||
|
||||
def to_bcf_date(date) |
||||
date.iso8601 |
||||
end |
||||
|
||||
def url_helpers |
||||
@url_helpers ||= OpenProject::StaticRouting::StaticUrlHelpers.new |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,182 @@ |
||||
## |
||||
# Creates or updates a BCF issue and markup from a work package |
||||
module OpenProject::Bcf::BcfXml |
||||
class ViewpointWriter < BaseWriter |
||||
attr_reader :viewpoint |
||||
|
||||
def initialize(viewpoint) |
||||
@viewpoint = viewpoint |
||||
super() |
||||
end |
||||
|
||||
def to_xml |
||||
doc.to_xml(indent: 2) |
||||
end |
||||
|
||||
def doc |
||||
@doc ||= begin |
||||
viewpoint_node = fetch(markup_doc, root_node.to_s) |
||||
|
||||
Nokogiri::XML::Builder.with(viewpoint_node) do |xml| |
||||
components xml |
||||
|
||||
camera('orthogonal_camera', xml) |
||||
camera('perspective_camera', xml) |
||||
|
||||
lines xml |
||||
clipping_planes xml |
||||
bitmaps xml |
||||
end |
||||
|
||||
markup_doc |
||||
end |
||||
end |
||||
|
||||
protected |
||||
|
||||
def root_node |
||||
:VisualizationInfo |
||||
end |
||||
|
||||
def root_node_attributes |
||||
{ Guid: viewpoint.uuid } |
||||
end |
||||
|
||||
def dig_json(*args) |
||||
viewpoint.json_viewpoint.dig(*args) |
||||
end |
||||
|
||||
def components(xml) |
||||
return unless dig_json('components') |
||||
|
||||
xml.Components do |
||||
view_setup_hints xml |
||||
selected_components xml |
||||
visibility xml |
||||
coloring xml |
||||
end |
||||
end |
||||
|
||||
def view_setup_hints(xml) |
||||
return unless (setup_hash = dig_json('components', 'visibility', 'view_setup_hints')) |
||||
|
||||
xml.ViewSetupHints(camelized(setup_hash)) |
||||
end |
||||
|
||||
def selected_components(xml) |
||||
return unless (selected = dig_json('components', 'selection')) |
||||
|
||||
xml.Selection do |
||||
selected.each do |comp_hash| |
||||
xml.Component camelized(comp_hash) |
||||
end |
||||
end |
||||
end |
||||
|
||||
def visibility(xml) |
||||
return unless (visibility_hash = dig_json 'components', 'visibility') |
||||
|
||||
xml.Visibility(DefaultVisibility: visibility_hash['default_visibility']) do |
||||
exceptions = visibility_hash['exceptions'] |
||||
next unless exceptions |
||||
|
||||
xml.Exceptions do |
||||
Array.wrap(exceptions).each do |comp_hash| |
||||
xml.Component camelized(comp_hash) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
def coloring(xml) |
||||
return unless (colors = dig_json 'components', 'coloring') |
||||
|
||||
xml.Coloring do |
||||
Array.wrap(colors).each do |color| |
||||
xml.Color Color: color['color'].delete_prefix('#') do |
||||
Array.wrap(color['components']).each do |comp_hash| |
||||
xml.Component camelized(comp_hash) |
||||
end |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
def camera(type, xml) |
||||
return unless (camera = dig_json(type)) |
||||
|
||||
xml.send(type.camelize) do |
||||
%w[CameraViewPoint CameraDirection CameraUpVector].each do |entry| |
||||
xml.send(entry) do |
||||
coords = camera[entry.underscore] |
||||
to_xml_coords(coords, xml) |
||||
end |
||||
end |
||||
xml.FieldOfView convert_float(camera['field_of_view']) |
||||
end |
||||
end |
||||
|
||||
def lines(xml) |
||||
return unless (lines = dig_json 'lines') |
||||
|
||||
xml.Lines do |
||||
Array.wrap(lines).each do |line| |
||||
xml.Line do |
||||
xml.StartPoint { to_xml_coords(line['start_point'], xml) } |
||||
xml.EndPoint { to_xml_coords(line['end_point'], xml) } |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
def clipping_planes(xml) |
||||
return unless (planes = dig_json 'clipping_planes') |
||||
|
||||
xml.ClippingPlanes do |
||||
Array.wrap(planes).each do |plane| |
||||
xml.ClippingPlane do |
||||
xml.Location { to_xml_coords(plane['location'], xml) } |
||||
xml.Direction { to_xml_coords(plane['direction'], xml) } |
||||
end |
||||
end |
||||
end |
||||
end |
||||
|
||||
def bitmaps(xml) |
||||
return unless (entries = dig_json 'bitmaps') |
||||
|
||||
# Bitmaps are rendered flat, whyever that is |
||||
entries.each do |bitmap| |
||||
xml.Bitmaps do |
||||
xml.Bitmap bitmap['bitmap_type'].upcase |
||||
xml.Reference bitmap['bitmap_data'] |
||||
xml.Location { to_xml_coords bitmap['location'], xml } |
||||
xml.Normal { to_xml_coords bitmap['normal'], xml } |
||||
xml.Up { to_xml_coords bitmap['up'], xml } |
||||
xml.Height convert_float(bitmap['height']) |
||||
end |
||||
end |
||||
end |
||||
|
||||
## |
||||
# Helper to transform a hash into camelized keys |
||||
def camelized(hash) |
||||
hash.transform_keys(&:camelize) |
||||
end |
||||
|
||||
## |
||||
# Convert a float to BCF format that strips |
||||
# insignificant zeros |
||||
def convert_float(val) |
||||
val.to_s.gsub(/(\.)0+$/, '') |
||||
end |
||||
|
||||
## |
||||
# Helper to render X,Y,Z hash as set of nodes |
||||
def to_xml_coords(hash, xml) |
||||
hash.each do |key, val| |
||||
xml.send(key.to_s.upcase, convert_float(val)) |
||||
end |
||||
end |
||||
end |
||||
end |
@ -0,0 +1,201 @@ |
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<VisualizationInfo Guid="{{UUID}}"> |
||||
<Components> |
||||
<Selection> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkc$"/> |
||||
<Component IfcGuid="2IzdhaXk1DxQeoZSeKbhcz"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyCk"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyCj"/> |
||||
<Component IfcGuid="2VwVShDiz0gAl$BsweUrbl"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyDZ"/> |
||||
<Component IfcGuid="30Vi1xXgzEtA72FJfoLgwc"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyCe"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyDR"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyBr"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkb$"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyDP"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyBn"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyDM"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkb_"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkcN"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyDK"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyDJ"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkcM"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkcL"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkcK"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkbZ"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkbY"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkcF"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyDB"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkcD"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkcC"/> |
||||
<Component IfcGuid="13osNZG6b1HvGnEwG5IBDr"/> |
||||
<Component IfcGuid="3W4DSy3pb33QWyGgzgo0pw"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkc8"/> |
||||
<Component IfcGuid="0E1Yt2xX98svHrdrMFg9cE"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkc7"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkc6"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkc5"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkc4"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkc2"/> |
||||
<Component IfcGuid="30Vi1xXgzEtA72FJfoLgxk"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkc1"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkc0"/> |
||||
<Component IfcGuid="2PzCZPHLj8bQL_hp3fERU1"/> |
||||
<Component IfcGuid="1s$t1FRQf40wjxOyV1OVTV"/> |
||||
<Component IfcGuid="13osNZG6b1HvGnEwG5IBE9"/> |
||||
<Component IfcGuid="1pc0TFRcjAywrRV3HgpmMS"/> |
||||
<Component IfcGuid="0wh07UsgP8mf3ADo8LWq7U"/> |
||||
<Component IfcGuid="2VwVShDiz0gAl$BsweUrbX"/> |
||||
<Component IfcGuid="0wh07UsgP8mf3ADo8LWq6X"/> |
||||
<Component IfcGuid="3LnOhZYmz8UQwRTZK9roX$"/> |
||||
<Component IfcGuid="3W4DSy3pb33QWyGgzgo0mc"/> |
||||
<Component IfcGuid="2MXBDcWRP02P5tfnBdrHNU"/> |
||||
<Component IfcGuid="2MXBDcWRP02P5tfnBdrHNT"/> |
||||
<Component IfcGuid="3W4DSy3pb33QWyGgzgo0o9"/> |
||||
<Component IfcGuid="3W4DSy3pb33QWyGgzgo0mW"/> |
||||
<Component IfcGuid="2MXBDcWRP02P5tfnBdrHNJ"/> |
||||
<Component IfcGuid="3bII83hyD6Yu$Mpez2jNcv"/> |
||||
<Component IfcGuid="1qQCUVUprErw_MLQ7DcWOJ"/> |
||||
<Component IfcGuid="1qQCUVUprErw_MLQ7DcWOI"/> |
||||
<Component IfcGuid="1qQCUVUprErw_MLQ7DcWVj"/> |
||||
<Component IfcGuid="1qQCUVUprErw_MLQ7DcWVi"/> |
||||
<Component IfcGuid="1qQCUVUprErw_MLQ7DcWO6"/> |
||||
<Component IfcGuid="1qQCUVUprErw_MLQ7DcWO5"/> |
||||
<Component IfcGuid="1qQCUVUprErw_MLQ7DcWO4"/> |
||||
<Component IfcGuid="2UWgTxbmTEourPAlYFxD8x"/> |
||||
<Component IfcGuid="2UWgTxbmTEourPAlYFxD8v"/> |
||||
<Component IfcGuid="2UWgTxbmTEourPAlYFxD8u"/> |
||||
<Component IfcGuid="1mLIVAU39AxPo7CJmxmiBM"/> |
||||
<Component IfcGuid="1gOilIRmfEGwb7$SzUoanJ"/> |
||||
<Component IfcGuid="2OyfaLLJzADAvG7yl7qlqI"/> |
||||
<Component IfcGuid="2OyfaLLJzADAvG7yl7qlnw"/> |
||||
<Component IfcGuid="0e0$1G54f40AFFxJYqAOJk"/> |
||||
<Component IfcGuid="2OyfaLLJzADAvG7yl7qlnr"/> |
||||
<Component IfcGuid="2UWgTxbmTEourPAlYFxD8d"/> |
||||
<Component IfcGuid="0e0$1G54f40AFFxJYqAOJi"/> |
||||
<Component IfcGuid="2UWgTxbmTEourPAlYFxD8c"/> |
||||
<Component IfcGuid="2UWgTxbmTEourPAlYFxD8a"/> |
||||
<Component IfcGuid="1qQCUVUprErw_MLQ7DcWOz"/> |
||||
<Component IfcGuid="1nQPsl2Nv5Uvj6quEKe7LN"/> |
||||
<Component IfcGuid="1qQCUVUprErw_MLQ7DcWO_"/> |
||||
<Component IfcGuid="1qQCUVUprErw_MLQ7DcWQN"/> |
||||
<Component IfcGuid="1qQCUVUprErw_MLQ7DcWPL"/> |
||||
<Component IfcGuid="2OyfaLLJzADAvG7yl7qln3"/> |
||||
<Component IfcGuid="2OyfaLLJzADAvG7yl7qln0"/> |
||||
<Component IfcGuid="0mQ6Us0RbAEwcMtmD0TDm6"/> |
||||
<Component IfcGuid="2OyfaLLJzADAvG7yl7qlm1"/> |
||||
<Component IfcGuid="1pc0TFRcjAywrRV3HgppMl"/> |
||||
<Component IfcGuid="1pc0TFRcjAywrRV3HgppMh"/> |
||||
<Component IfcGuid="1pc0TFRcjAywrRV3HgppMf"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkjh"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkjg"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkiv"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkjf"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkja"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkj7"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkhV"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkj6"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkhU"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkhT"/> |
||||
<Component IfcGuid="0zsqKw7957Bh4NNjGz39d0"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkhS"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkj3"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkj2"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkhR"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkhQ"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkj1"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkj0"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkhP"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkhO"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkhM"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkhL"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkhK"/> |
||||
<Component IfcGuid="1gOilIRmfEGwb7$SzUohOS"/> |
||||
<Component IfcGuid="1azD0$4TTC1hgVDVWx5ITK"/> |
||||
<Component IfcGuid="1azD0$4TTC1hgVDVWx5ITI"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkjX"/> |
||||
<Component IfcGuid="0LHXUGtOLEzvvIxaK5XMWV"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkjW"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkjT"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkjS"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkjR"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyAn"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyAl"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkjN"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyAk"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkjM"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkjL"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyAi"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyD9"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkjK"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyD8"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkjJ"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkhi"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkjI"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyBV"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyAf"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkjH"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkjG"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyBR"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyAb"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyD2"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyBQ"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyBO"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyBL"/> |
||||
<Component IfcGuid="2Cc$KVYf55mfjggfx$IIb9"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyBK"/> |
||||
<Component IfcGuid="2Cc$KVYf55mfjggfx$IIb7"/> |
||||
<Component IfcGuid="2Cc$KVYf55mfjggfx$IIb6"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkbz"/> |
||||
<Component IfcGuid="0LHXUGtOLEzvvIxaK5XMW8"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyBG"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkby"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyBF"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkch"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyBE"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyBC"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkcf"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkbu"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkbt"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyBA"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkca"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkbp"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkbo"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkbn"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkbm"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyB3"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkdD"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyB0"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkcR"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkcQ"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkcP"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkh2"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkh1"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyDt"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkcv"/> |
||||
<Component IfcGuid="39_n9ZMhPAQBWcKbXoFkcu"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyDq"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyDk"/> |
||||
<Component IfcGuid="1Uhsb9oeb77OoM87lbwyDf"/> |
||||
</Selection> |
||||
</Components> |
||||
<PerspectiveCamera> |
||||
<CameraViewPoint> |
||||
<X>58.1038</X> |
||||
<Y>16.5493</Y> |
||||
<Z>24.7329</Z> |
||||
</CameraViewPoint> |
||||
<CameraDirection> |
||||
<X>1.28974</X> |
||||
<Y>1.2105</Y> |
||||
<Z>-0.569962</Z> |
||||
</CameraDirection> |
||||
<CameraUpVector> |
||||
<X>0.223629</X> |
||||
<Y>0.209889</Y> |
||||
<Z>0.951807</Z> |
||||
</CameraUpVector> |
||||
<FieldOfView>60</FieldOfView> |
||||
</PerspectiveCamera> |
||||
</VisualizationInfo> |
@ -0,0 +1,96 @@ |
||||
#-- copyright |
||||
# OpenProject is a project management system. |
||||
# Copyright (C) 2012-2019 the OpenProject Foundation (OPF) |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License version 3. |
||||
# |
||||
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: |
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang |
||||
# Copyright (C) 2010-2013 the ChiliProject Team |
||||
# |
||||
# This program is free software; you can redistribute it and/or |
||||
# modify it under the terms of the GNU General Public License |
||||
# as published by the Free Software Foundation; either version 2 |
||||
# of the License, or (at your option) any later version. |
||||
# |
||||
# This program is distributed in the hope that it will be useful, |
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
# GNU General Public License for more details. |
||||
# |
||||
# You should have received a copy of the GNU General Public License |
||||
# along with this program; if not, write to the Free Software |
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
||||
# |
||||
# See docs/COPYRIGHT.rdoc for more details. |
||||
#++ |
||||
|
||||
require 'spec_helper' |
||||
require 'compare-xml' |
||||
|
||||
describe OpenProject::Bcf::BcfXml::ViewpointWriter do |
||||
let(:writer_instance) { described_class.new json_resource } |
||||
let(:reader_instance) { ::OpenProject::Bcf::BcfJson::ViewpointReader.new xml_resource.uuid, subject.to_xml } |
||||
let(:xml_comparison) { Nokogiri::XML(xml_resource.viewpoint) } |
||||
let(:json_comparison) { json_resource.raw_json_viewpoint } |
||||
|
||||
subject { writer_instance.doc } |
||||
|
||||
shared_examples 'converts back to xml' do |
||||
it 'the output of writer is XML-equal to the provided XML viewpoint' do |
||||
results = CompareXML.equivalent?( |
||||
subject, |
||||
xml_comparison, |
||||
collapse_whitespace: false, |
||||
verbose: true |
||||
) |
||||
|
||||
if results.length > 0 |
||||
puts subject.to_xml |
||||
raise "Expected documents to be equal. Found diffs:\n#{results.join("\n")}" |
||||
end |
||||
end |
||||
|
||||
it 'contains the root node' do |
||||
expect(writer_instance.doc.at('VisualizationInfo')).to be_present |
||||
end |
||||
|
||||
it 'goes full circle comparing back to JSON' do |
||||
expect(reader_instance.to_json).to be_json_eql json_comparison |
||||
end |
||||
end |
||||
|
||||
describe 'with minimal example' do |
||||
let_it_be(:json_resource) do |
||||
FactoryBot.build_stubbed :bcf_viewpoint, uuid: '{{UUID}}', viewpoint_name: 'minimal.bcfv' |
||||
end |
||||
let_it_be(:xml_resource) do |
||||
FactoryBot.build_stubbed :xml_viewpoint, uuid: '{{UUID}}', viewpoint_name: 'minimal.bcfv' |
||||
end |
||||
|
||||
it_behaves_like 'converts back to xml' |
||||
end |
||||
|
||||
describe 'with full viewpoint' do |
||||
let_it_be(:json_resource) do |
||||
FactoryBot.build_stubbed :bcf_viewpoint, uuid: '{{UUID}}', viewpoint_name: 'full_viewpoint.bcfv' |
||||
end |
||||
let_it_be(:xml_resource) do |
||||
FactoryBot.build_stubbed :xml_viewpoint, uuid: '{{UUID}}', viewpoint_name: 'full_viewpoint.bcfv' |
||||
end |
||||
|
||||
it_behaves_like 'converts back to xml' |
||||
end |
||||
|
||||
describe 'with real-world neuhaus_sc_1 example' do |
||||
let_it_be(:json_resource) do |
||||
FactoryBot.build_stubbed :bcf_viewpoint, uuid: '{{UUID}}', viewpoint_name: 'neubau_sc_1.bcfv' |
||||
end |
||||
let_it_be(:xml_resource) do |
||||
FactoryBot.build_stubbed :xml_viewpoint, uuid: '{{UUID}}', viewpoint_name: 'neubau_sc_1_fixed.bcfv' |
||||
end |
||||
|
||||
it_behaves_like 'converts back to xml' |
||||
end |
||||
end |
Loading…
Reference in new issue