From c2bef232b6e15144ec5ca33a9736105539f86856 Mon Sep 17 00:00:00 2001 From: Balint-H Date: Thu, 14 Mar 2024 12:38:56 +0000 Subject: [PATCH 01/51] Handle the implicit auto value for limits now written by the compiler to the xml --- .../Components/Joints/MjJointSettings.cs | 9 +------- unity/Runtime/Components/MjActuator.cs | 11 ++++------ unity/Runtime/Tools/XmlElementExtensions.cs | 22 +++++++++++++++++++ 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/unity/Runtime/Components/Joints/MjJointSettings.cs b/unity/Runtime/Components/Joints/MjJointSettings.cs index 322d6568..46da927c 100644 --- a/unity/Runtime/Components/Joints/MjJointSettings.cs +++ b/unity/Runtime/Components/Joints/MjJointSettings.cs @@ -165,14 +165,7 @@ namespace Mujoco { ImpFriction.FromMjcf(mjcf, "solimpfriction"); FrictionLoss = mjcf.GetFloatAttribute("frictionloss", 0.0f); - bool defaultLimited = false; - if ((mjcf.OwnerDocument.GetElementsByTagName("compiler")[0]?["compiler"]) - ?.GetBoolAttribute("autolimits", true) ?? - true) { - defaultLimited = mjcf.HasAttribute("range"); - } - - Limited = mjcf.GetBoolAttribute("limited", defaultLimited); + Limited = mjcf.GetLimitedAttribute("limited", mjcf.HasAttribute("range")); Margin = mjcf.GetFloatAttribute("margin", defaultValue: 0.0f); } } diff --git a/unity/Runtime/Components/MjActuator.cs b/unity/Runtime/Components/MjActuator.cs index 9aacf2bf..e44b8579 100644 --- a/unity/Runtime/Components/MjActuator.cs +++ b/unity/Runtime/Components/MjActuator.cs @@ -82,13 +82,10 @@ public class MjActuator : MjComponent { LengthRange = mjcf.GetVector2Attribute("lengthrange", defaultValue: Vector2.zero); Gear = mjcf.GetFloatArrayAttribute("gear", defaultValue: new float[] { 1.0f }).ToList(); - bool autolimits = (mjcf.OwnerDocument.GetElementsByTagName("compiler")[0]?["compiler"]) - ?.GetBoolAttribute("autolimits", true) ?? - false; - CtrlLimited = mjcf.GetBoolAttribute("ctrllimited", - defaultValue: autolimits ? CtrlRange != Vector2.zero : false); - ForceLimited = mjcf.GetBoolAttribute("forcelimited", - defaultValue: autolimits ? ForceRange != Vector2.zero : false); + CtrlLimited = mjcf.GetLimitedAttribute("ctrllimited", + rangeDefined: mjcf.HasAttribute("ctrlrange")); + ForceLimited = mjcf.GetLimitedAttribute("forcelimited", + rangeDefined: mjcf.HasAttribute("forcerange")); } } diff --git a/unity/Runtime/Tools/XmlElementExtensions.cs b/unity/Runtime/Tools/XmlElementExtensions.cs index 246f3d34..9dd8996a 100644 --- a/unity/Runtime/Tools/XmlElementExtensions.cs +++ b/unity/Runtime/Tools/XmlElementExtensions.cs @@ -37,6 +37,28 @@ public static class XmlElementExtensions { } } + public static bool GetLimitedAttribute( + this XmlElement element, string name, bool rangeDefined) { + var strValue = element.GetStringAttribute(name, "auto"); + if (strValue == "auto" && rangeDefined && element.GetAutolimitsEnabled()) return true; + if (strValue == "auto") return false; + + bool parsedValue; + if (bool.TryParse(strValue, out parsedValue)) { + return parsedValue; + } else { + throw new ArgumentException($"'{strValue}' is not a bool."); + } + } + + public static bool GetAutolimitsEnabled( + this XmlElement element) { + bool autolimits = (element.OwnerDocument?.GetElementsByTagName("compiler")[0]?["compiler"]) + ?.GetBoolAttribute("autolimits", true) ?? + true; + return autolimits; + } + public static float GetFloatAttribute( this XmlElement element, string name, float defaultValue = 0.0f) { if (!element.HasAttribute(name)) { From f818a16ae49ae650acab273f2bd3e86609f7c18b Mon Sep 17 00:00:00 2001 From: Baruch Tabanpour Date: Thu, 14 Mar 2024 09:40:29 -0700 Subject: [PATCH 02/51] Fix the bugfix for capsule-convex collisions. PiperOrigin-RevId: 615809115 Change-Id: I183336630a76a9ada5b0730559b49779dd94f8e5 --- mjx/mujoco/mjx/_src/collision_convex.py | 34 ++++++++++++-------- mjx/mujoco/mjx/_src/collision_driver_test.py | 34 ++++++++++++++++---- mjx/mujoco/mjx/_src/math.py | 18 ++--------- 3 files changed, 50 insertions(+), 36 deletions(-) diff --git a/mjx/mujoco/mjx/_src/collision_convex.py b/mjx/mujoco/mjx/_src/collision_convex.py index 6095994f..30e64401 100644 --- a/mjx/mujoco/mjx/_src/collision_convex.py +++ b/mjx/mujoco/mjx/_src/collision_convex.py @@ -302,12 +302,12 @@ def capsule_convex(cap: GeomInfo, convex: GeomInfo) -> Contact: # the face. edge_p0 = jp.roll(face, 1, axis=0) edge_p1 = face - edge_normals = jax.vmap(jp.cross, in_axes=[0, None])( + side_planes = jax.vmap(jp.cross, in_axes=[0, None])( edge_p1 - edge_p0, normal, ) cap_pts_clipped, mask = _clip_edge_to_planes( - cap_pts[0], cap_pts[1], edge_p0, edge_normals + cap_pts[0], cap_pts[1], edge_p0, side_planes ) cap_pts_clipped = cap_pts_clipped - normal * cap.size[0] face_pts = jax.vmap(_project_pt_onto_plane, in_axes=[0, None, None])( @@ -321,28 +321,34 @@ def capsule_convex(cap: GeomInfo, convex: GeomInfo) -> Contact: ) # Get a potential edge contact. - edge_closest, cap_closest, t_a, t_b = jax.vmap( - math.closest_segment_to_segment_points_w_barycentric, + edge_closest, cap_closest = jax.vmap( + math.closest_segment_to_segment_points, in_axes=[0, 0, None, None], )(edge_p0, edge_p1, cap_pts[0], cap_pts[1]) e_idx = ((edge_closest - cap_closest) ** 2).sum(axis=1).argmin() cap_closest_pt, edge_closest_pt = cap_closest[e_idx], edge_closest[e_idx] - edge_dist = math.norm(cap_closest_pt - edge_closest_pt) - t_a, t_b = t_a[e_idx], t_b[e_idx] - in_segment = ((t_a > 0) & (t_a < 1)) | ((t_b > 0) & (t_b < 1)) - # Ensure edge_axis points towards the convex centroid. - edge_axis = jp.cross(edge_p0[e_idx] - edge_p1[e_idx], axis) - sign = jp.where(jp.dot(edge_closest_pt, edge_axis) < 0, 1, -1) - edge_axis *= sign - degenerate_edge_axis = (edge_axis**2).sum() < 1e-6 - edge_axis = math.normalize(edge_axis) + edge_dir = edge_closest_pt - cap_closest_pt + degenerate_edge_dir = jp.sum(jp.square(edge_dir)) < 1e-6 + edge_dir, edge_dist = math.normalize_with_norm(edge_dir) + face_edge_normals = convex.face_edge_normal[best_idx][e_idx] + in_edge_voronoi = ((face_edge_normals @ edge_dir) < 0).all() + edge_axis = math.normalize(-edge_closest_pt) # approximate edge axis + edge_axis = jp.where( + ~degenerate_edge_dir & in_edge_voronoi, + edge_dir, # shallow edge penetration + edge_axis, # deep edge penetration + ) # Determine edge contact position. edge_pos = ( edge_closest_pt + (cap_closest_pt + edge_axis * cap.size[0]) ) * 0.5 edge_penetration = cap.size[0] - edge_dist - has_edge_contact = (edge_penetration > 0) & in_segment & ~degenerate_edge_axis + # prefer face contact if the edge axis is parallel to the face normal + edge_dir_parallel_to_face = ( + jp.abs(edge_dir.dot(normal)) > 0.99 + ) & ~degenerate_edge_dir + has_edge_contact = (edge_penetration > 0) & ~edge_dir_parallel_to_face # Get the contact info. pos = jp.where(has_edge_contact, pos.at[0].set(edge_pos), pos) diff --git a/mjx/mujoco/mjx/_src/collision_driver_test.py b/mjx/mujoco/mjx/_src/collision_driver_test.py index 7eda941d..c914ad5c 100644 --- a/mjx/mujoco/mjx/_src/collision_driver_test.py +++ b/mjx/mujoco/mjx/_src/collision_driver_test.py @@ -248,8 +248,8 @@ class CapsuleCollisionTest(parameterized.TestCase): """ - def test_capsule_convex(self): - """Tests a capsule-convex collision for a face contact.""" + def test_capsule_convex_face(self): + """Tests face contact.""" d, dx = _collide(self._CAP_BOX) # sort positions for comparison @@ -263,7 +263,8 @@ class CapsuleCollisionTest(parameterized.TestCase): for field in dataclasses.fields(Contact): _assert_attr_eq(dx.contact, d.contact, field.name, 'capsule_convex', 1e-4) - # test deep face penetration + def test_capsule_convex_face_deep(self): + """Tests deep face penetration.""" xml = self._CAP_BOX.replace('', '') _, dx = _collide(xml) @@ -294,7 +295,7 @@ class CapsuleCollisionTest(parameterized.TestCase): """ def test_capsule_convex_edge(self): - """Tests a capsule-convex collision for an edge contact.""" + """Tests edge contact.""" d, dx = _collide(self._CAP_EDGE_BOX) c = dx.contact @@ -305,19 +306,38 @@ class CapsuleCollisionTest(parameterized.TestCase): for field in dataclasses.fields(Contact): _assert_attr_eq(c, d.contact, field.name, 'capsule_convex_edge', 1e-4) - # test deep edge penetration + def test_capsule_convex_edge_deep(self): + """Tests deep edge penetration.""" xml = self._CAP_EDGE_BOX.replace( ' Tuple[jax.Array, jax.Array, jax.Array, jax.Array]: +) -> Tuple[jax.Array, jax.Array]: """Returns closest points between two line segments.""" # Gets the closest segment points by first finding the closest points # between two lines. Points are then clipped to be on the line segments @@ -364,10 +364,6 @@ def closest_segment_to_segment_points_w_barycentric( t_a = jp.clip(orig_t_a, -half_len_a, half_len_a) t_b = jp.clip(orig_t_b, -half_len_b, half_len_b) - # reparametrize t_a, t_b - t_a_01 = (orig_t_a + half_len_a) / jp.maximum(len_a, 1e-6) - t_b_01 = (orig_t_b + half_len_b) / jp.maximum(len_b, 1e-6) - best_a = a_mid + dir_a * t_a best_b = b_mid + dir_b * t_b @@ -381,12 +377,4 @@ def closest_segment_to_segment_points_w_barycentric( best_a = jp.where(d1 < d2, new_a, best_a) best_b = jp.where(d1 < d2, best_b, new_b) - return best_a, best_b, t_a_01, t_b_01 - - -def closest_segment_to_segment_points( - a0: jax.Array, a1: jax.Array, b0: jax.Array, b1: jax.Array -) -> Tuple[jax.Array, jax.Array]: - """Returns closest points between two line segments.""" - a, b, *_ = closest_segment_to_segment_points_w_barycentric(a0, a1, b0, b1) - return a, b + return best_a, best_b From e5811ce2b48a479618dd7fbfb17ace3e6798ef0c Mon Sep 17 00:00:00 2001 From: Baruch Tabanpour Date: Thu, 14 Mar 2024 14:14:31 -0700 Subject: [PATCH 03/51] Further improve edge contact for capsule-convex. PiperOrigin-RevId: 615900645 Change-Id: I7fd495b10b7b3121da7aa5ed15cde413d916bc84 --- mjx/mujoco/mjx/_src/collision_convex.py | 12 ++++++--- mjx/mujoco/mjx/_src/collision_driver_test.py | 27 +++++++++++++++++++- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/mjx/mujoco/mjx/_src/collision_convex.py b/mjx/mujoco/mjx/_src/collision_convex.py index 30e64401..ce3e41e2 100644 --- a/mjx/mujoco/mjx/_src/collision_convex.py +++ b/mjx/mujoco/mjx/_src/collision_convex.py @@ -331,10 +331,12 @@ def capsule_convex(cap: GeomInfo, convex: GeomInfo) -> Contact: degenerate_edge_dir = jp.sum(jp.square(edge_dir)) < 1e-6 edge_dir, edge_dist = math.normalize_with_norm(edge_dir) face_edge_normals = convex.face_edge_normal[best_idx][e_idx] - in_edge_voronoi = ((face_edge_normals @ edge_dir) < 0).all() + inside_edge_voronoi_front = ((face_edge_normals @ edge_dir) < 0).all() + inside_edge_voronoi_back = ((face_edge_normals @ edge_dir) > 0).all() + outside_edge_voronoi = ~inside_edge_voronoi_front & ~inside_edge_voronoi_back edge_axis = math.normalize(-edge_closest_pt) # approximate edge axis edge_axis = jp.where( - ~degenerate_edge_dir & in_edge_voronoi, + ~degenerate_edge_dir & inside_edge_voronoi_front, edge_dir, # shallow edge penetration edge_axis, # deep edge penetration ) @@ -348,7 +350,11 @@ def capsule_convex(cap: GeomInfo, convex: GeomInfo) -> Contact: edge_dir_parallel_to_face = ( jp.abs(edge_dir.dot(normal)) > 0.99 ) & ~degenerate_edge_dir - has_edge_contact = (edge_penetration > 0) & ~edge_dir_parallel_to_face + has_edge_contact = ( + (edge_penetration > 0) + & ~edge_dir_parallel_to_face + & ~outside_edge_voronoi + ) # Get the contact info. pos = jp.where(has_edge_contact, pos.at[0].set(edge_pos), pos) diff --git a/mjx/mujoco/mjx/_src/collision_driver_test.py b/mjx/mujoco/mjx/_src/collision_driver_test.py index c914ad5c..858e8795 100644 --- a/mjx/mujoco/mjx/_src/collision_driver_test.py +++ b/mjx/mujoco/mjx/_src/collision_driver_test.py @@ -323,6 +323,8 @@ class CapsuleCollisionTest(parameterized.TestCase): def test_capsule_convex_edge_shallow_tip(self): """Tests shallow edge penetration on the tip of the capsule.""" + # the capsule sphere is inside the edge voronoi region, so there is an + # edge contact xml = self._CAP_EDGE_BOX.replace( ' Date: Thu, 14 Mar 2024 15:50:16 -0700 Subject: [PATCH 04/51] Fix bug where treedef for mjx.make_data doesn't match mjx.put_data. PiperOrigin-RevId: 615928973 Change-Id: I08af97ac0300b9d51c1f4b46d48dde98d24197fa --- doc/changelog.rst | 1 + mjx/mujoco/mjx/_src/io.py | 5 ++++- mjx/mujoco/mjx/_src/io_test.py | 15 +++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/doc/changelog.rst b/doc/changelog.rst index bb66f206..fdfafeef 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -10,6 +10,7 @@ MJX 1. Improved performance of SAT for convex collisions. 2. Fixed bug for sphere/capsule-convex deep penetration. +3. Fixed bug where ``mjx.Data`` produced by ``mjx.put_data`` had different treedef than ``mjx.make_data``. Version 3.1.3 (March 5th, 2024) ----------------------------------- diff --git a/mjx/mujoco/mjx/_src/io.py b/mjx/mujoco/mjx/_src/io.py index 4b0c2f4f..ddcd8907 100644 --- a/mjx/mujoco/mjx/_src/io.py +++ b/mjx/mujoco/mjx/_src/io.py @@ -172,7 +172,7 @@ def make_data(m: Union[types.Model, mujoco.MjModel]) -> types.Data: ctrl=zero_nu, qfrc_applied=zero_nv, xfrc_applied=zero_nbody_6, - eq_active=jp.zeros(m.neq, dtype=int), + eq_active=jp.zeros(m.neq, dtype=jp.uint8), qacc=zero_nv, act_dot=zero_na, xpos=zero_nbody_3, @@ -374,6 +374,9 @@ def put_data(m: mujoco.MjModel, d: mujoco.MjData, device=None) -> types.Data: for fname in ('xmat', 'ximat', 'geom_xmat', 'site_xmat', 'cam_xmat'): fields[fname] = fields[fname].reshape((-1, 3, 3)) + # MJX does not support islanding, so only transfer the first solver_niter + fields['solver_niter'] = fields['solver_niter'][0] + # pad efc fields: MuJoCo efc arrays are sparse for inactive constraints. # efc_J is also optionally column-sparse (typically for large nv). MJX is # neither: it contains zeros for inactive constraints, and efc_J is always diff --git a/mjx/mujoco/mjx/_src/io_test.py b/mjx/mujoco/mjx/_src/io_test.py index 9ceca6b0..e3f414df 100644 --- a/mjx/mujoco/mjx/_src/io_test.py +++ b/mjx/mujoco/mjx/_src/io_test.py @@ -434,5 +434,20 @@ class DataIOTest(parameterized.TestCase): self.assertEqual(d_2.contact.frame.shape, (1, 9)) np.testing.assert_allclose(d_2.contact.frame, d.contact.frame) + def test_make_matches_put(self): + """Test that make_data produces a pytree that matches put_data.""" + + m = mujoco.MjModel.from_xml_string(_MULTIPLE_CONSTRAINTS) + d = mujoco.MjData(m) + mujoco.mj_step(m, d, 2) + dx = mjx.put_data(m, d) + + step_fn = lambda d: d.replace(time=d.time + 1) + step_fn_jit = jax.jit(step_fn).lower(dx).compile() + + # placing an MjData onto device should yield the same treedef mjx.Data as + # calling make_data. they should be interchangeable for jax functions: + step_fn_jit(mjx.make_data(m)) + if __name__ == '__main__': absltest.main() From 2386353b02c2239fc968e6d6e04b091c6085e038 Mon Sep 17 00:00:00 2001 From: Baruch Tabanpour Date: Thu, 14 Mar 2024 16:20:04 -0700 Subject: [PATCH 05/51] Throw an error for margin/gap with meshes. PiperOrigin-RevId: 615937263 Change-Id: I3289cf1b1fec93385cc78a01e53866427453db59 --- doc/changelog.rst | 1 + doc/mjx.rst | 20 +++++------ mjx/mujoco/mjx/__init__.py | 1 + mjx/mujoco/mjx/_src/collision_driver.py | 46 +++++++++++++++---------- mjx/mujoco/mjx/_src/device.py | 9 +++-- mjx/mujoco/mjx/_src/io.py | 10 ++++-- mjx/mujoco/mjx/_src/io_test.py | 19 ++++++++++ 7 files changed, 73 insertions(+), 33 deletions(-) diff --git a/doc/changelog.rst b/doc/changelog.rst index fdfafeef..e32cd0a5 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -11,6 +11,7 @@ MJX 1. Improved performance of SAT for convex collisions. 2. Fixed bug for sphere/capsule-convex deep penetration. 3. Fixed bug where ``mjx.Data`` produced by ``mjx.put_data`` had different treedef than ``mjx.make_data``. +4. Throw an error for margin/gap for convex mesh collisions, since they are not supported. Version 3.1.3 (March 5th, 2024) ----------------------------------- diff --git a/doc/mjx.rst b/doc/mjx.rst index 3d1d42d2..330336ee 100644 --- a/doc/mjx.rst +++ b/doc/mjx.rst @@ -215,6 +215,14 @@ The following features are **in development** and coming soon: * - Category - Feature + * - :ref:`Geom ` + - ``SDF``, ``HFIELD``, ``ELLIPSOID``, ``CYLINDER`` + * - :ref:`Condim ` + - 1, 4, 6 + * - :ref:`Constraint ` + - :ref:`Frictionloss `, ``CONTACT_FRICTIONLESS``, ``CONTACT_ELLIPTIC``, ``FRICTION_DOF`` + * - :ref:`Integrator ` + - ``IMPLICIT``, ``IMPLICITFAST`` * - Dynamics - :ref:`Inverse ` * - :ref:`Transmission ` @@ -227,16 +235,8 @@ The following features are **in development** and coming soon: - ``MUSCLE`` * - :ref:`Tendon Wrapping ` - ``NONE``, ``JOINT``, ``PULLEY``, ``SITE``, ``SPHERE``, ``CYLINDER`` - * - :ref:`Geom ` - - ``HFIELD``, ``ELLIPSOID``, ``CYLINDER`` - * - :ref:`Constraint ` - - :ref:`Frictionloss `, ``CONTACT_FRICTIONLESS``, ``CONTACT_ELLIPTIC``, ``FRICTION_DOF`` - * - :ref:`Integrator ` - - ``IMPLICIT``, ``IMPLICITFAST`` * - :ref:`Cone ` - ``ELLIPTIC`` - * - :ref:`Condim ` - - 1, 4, 6 * - Fluid Model - :ref:`flEllipsoid` * - :ref:`Tendons ` @@ -258,6 +258,8 @@ The following features are **unsupported**: * - Category - Feature + * - :ref:`margin` and :ref:`gap` + - Unimplemented for collisions with ``Mesh`` :ref:`Geom `. * - :ref:`Transmission ` - ``TRN_JOINTINPARENT``, ``TRN_SLIDERCRANK``, ``TRN_BODY`` * - :ref:`Actuator Dynamics ` @@ -270,8 +272,6 @@ The following features are **unsupported**: - ``PGS`` * - :ref:`Sensors ` - ``PLUGIN``, ``USER`` - * - :ref:`Geom ` - - ``SDF`` .. _MjxSharpBits: diff --git a/mjx/mujoco/mjx/__init__.py b/mjx/mujoco/mjx/__init__.py index 472356b0..e21b14fd 100644 --- a/mjx/mujoco/mjx/__init__.py +++ b/mjx/mujoco/mjx/__init__.py @@ -16,6 +16,7 @@ # pylint:disable=g-importing-member from mujoco.mjx._src.collision_driver import collision +from mujoco.mjx._src.collision_driver import get_params from mujoco.mjx._src.collision_driver import ncon from mujoco.mjx._src.constraint import count_constraints from mujoco.mjx._src.constraint import make_constraint diff --git a/mjx/mujoco/mjx/_src/collision_driver.py b/mjx/mujoco/mjx/_src/collision_driver.py index d492d69b..3b70990c 100644 --- a/mjx/mujoco/mjx/_src/collision_driver.py +++ b/mjx/mujoco/mjx/_src/collision_driver.py @@ -14,7 +14,7 @@ # ============================================================================== """Collide geometries.""" -from typing import Callable, Dict, Optional, Sequence, Tuple, Union +from typing import Callable, Dict, List, Optional, Sequence, Tuple, Union import jax from jax import numpy as jp @@ -187,6 +187,31 @@ def _dynamic_params( return SolverParams(friction, solref, solreffriction, solimp, margin, gap) +def get_params( + m: Union[Model, mujoco.MjModel], candidates: Sequence[Candidate] +) -> Tuple[List[int], List[int], SolverParams]: + """Gets solver params for a list of collision candidates.""" + # group sol params by different candidate types + typ_cands = {} + for c in candidates: + typ = (c.ipair > -1, c.geomp > -1) + typ_cands.setdefault(typ, []).append(c) + + geom1, geom2, params = [], [], [] + for (pair, priority), candidates in typ_cands.items(): + geom1.extend([c.geom1 for c in candidates]) + geom2.extend([c.geom2 for c in candidates]) + if pair: + params.append(_pair_params(m, candidates)) + elif priority: + params.append(_priority_params(m, candidates)) + else: + params.append(_dynamic_params(m, candidates)) + + params = jax.tree_map(lambda *x: jp.concatenate(x), *params) + return geom1, geom2, params + + def _pair_info( m: Model, d: Data, geom1: Sequence[int], geom2: Sequence[int] ) -> Tuple[GeomInfo, GeomInfo, Sequence[Dict[str, Optional[int]]]]: @@ -276,24 +301,7 @@ def _collide_geoms( if not fn: return Contact.zero() - # group sol params by different candidate types - typ_cands = {} - for c in candidates: - typ = (c.ipair > -1, c.geomp > -1) - typ_cands.setdefault(typ, []).append(c) - - geom1, geom2, params = [], [], [] - for (pair, priority), candidates in typ_cands.items(): - geom1.extend([c.geom1 for c in candidates]) - geom2.extend([c.geom2 for c in candidates]) - if pair: - params.append(_pair_params(m, candidates)) - elif priority: - params.append(_priority_params(m, candidates)) - else: - params.append(_dynamic_params(m, candidates)) - - params = jax.tree_map(lambda *x: jp.concatenate(x), *params) + geom1, geom2, params = get_params(m, candidates) g1, g2, in_axes = _pair_info(m, d, geom1, geom2) # Run a crude version of broadphase. diff --git a/mjx/mujoco/mjx/_src/device.py b/mjx/mujoco/mjx/_src/device.py index 0d094210..b920b2e6 100644 --- a/mjx/mujoco/mjx/_src/device.py +++ b/mjx/mujoco/mjx/_src/device.py @@ -138,8 +138,7 @@ def _validate(m: mujoco.MjModel): raise NotImplementedError('Tendons are not supported.') # check collision geom types - candidate_set = collision_driver.collision_candidates(m) - for g1, g2, *_ in candidate_set: + for (g1, g2, *_), c in collision_driver.collision_candidates(m).items(): g1, g2 = mujoco.mjtGeom(g1), mujoco.mjtGeom(g2) if g1 == mujoco.mjtGeom.mjGEOM_PLANE and g2 in ( mujoco.mjtGeom.mjGEOM_PLANE, @@ -149,6 +148,12 @@ def _validate(m: mujoco.MjModel): continue if collision_driver.get_collision_fn((g1, g2)) is None: raise NotImplementedError(f'({g1}, {g2}) collisions not implemented.') + *_, params = collision_driver.get_params(m, c) + margin_gap = not np.allclose(np.concatenate([params.margin, params.gap]), 0) + if mujoco.mjtGeom.mjGEOM_MESH in (g1, g2) and margin_gap: + raise NotImplementedError( + f'Margin and gap not implemented for ({g1}, {g2})' + ) # TODO(erikfrey): warn for high solver iterations, nefc, etc. diff --git a/mjx/mujoco/mjx/_src/io.py b/mjx/mujoco/mjx/_src/io.py index ddcd8907..1958829f 100644 --- a/mjx/mujoco/mjx/_src/io.py +++ b/mjx/mujoco/mjx/_src/io.py @@ -91,10 +91,16 @@ def put_model(m: mujoco.MjModel, device=None) -> types.Model: raise NotImplementedError('only condim=3 is supported') # check collision geom types - for g1, g2, *_ in collision_driver.collision_candidates(m): + for (g1, g2, *_), c in collision_driver.collision_candidates(m).items(): + g1, g2 = mujoco.mjtGeom(g1), mujoco.mjtGeom(g2) if collision_driver.get_collision_fn((g1, g2)) is None: - g1, g2 = mujoco.mjtGeom(g1), mujoco.mjtGeom(g2) raise NotImplementedError(f'({g1}, {g2}) has no collision function') + *_, params = collision_driver.get_params(m, c) + margin_gap = not np.allclose(np.concatenate([params.margin, params.gap]), 0) + if mujoco.mjtGeom.mjGEOM_MESH in (g1, g2) and margin_gap: + raise NotImplementedError( + f'Margin and gap not implemented for ({g1}, {g2})' + ) for enum_field, enum_type, mj_type in ( (m.actuator_biastype, types.BiasType, mujoco.mjtBias), diff --git a/mjx/mujoco/mjx/_src/io_test.py b/mjx/mujoco/mjx/_src/io_test.py index e3f414df..83147503 100644 --- a/mjx/mujoco/mjx/_src/io_test.py +++ b/mjx/mujoco/mjx/_src/io_test.py @@ -209,6 +209,25 @@ class ModelIOTest(parameterized.TestCase): """)) + def test_margin_gap_mesh_not_implemented(self): + with self.assertRaises(NotImplementedError): + mjx.put_model(mujoco.MjModel.from_xml_string(""" + + + + + + + + + + + + + + + """)) + class DataIOTest(parameterized.TestCase): """IO tests for mjx.Data.""" From 9fef77193f1687437de6ba49c95da77ee538387d Mon Sep 17 00:00:00 2001 From: Kyle Bayes Date: Thu, 14 Mar 2024 18:27:09 -0700 Subject: [PATCH 06/51] Fix V -> B typo in lookup table for encoding Base64. PiperOrigin-RevId: 615968363 Change-Id: I1dae697462afcae48442610b1fe4acab93b6d62d --- src/engine/engine_util_misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/engine_util_misc.c b/src/engine/engine_util_misc.c index 7199555e..3903d68b 100644 --- a/src/engine/engine_util_misc.c +++ b/src/engine/engine_util_misc.c @@ -639,7 +639,7 @@ static uint32_t _decode(char ch) { // returns number of chars written in buf: 4 * [(ndata + 2) / 3] + 1 size_t mju_encodeBase64(char* buf, const uint8_t* data, size_t ndata) { static const char *table = - "ABCDEFGHIJKLMNOPQRSTUBWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int i = 0, j = 0; From a23cb4d22cfbbaa7fddcf4ab9dbc803f4e566020 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Fri, 15 Mar 2024 06:56:53 -0700 Subject: [PATCH 07/51] Cite Vaxenburg et al. in fluid force documentation. PiperOrigin-RevId: 616114884 Change-Id: I0e7db61820c6ece118dee6871b8a526fdb79fb02 --- doc/computation/fluid.rst | 4 +--- doc/references.bib | 11 +++++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/doc/computation/fluid.rst b/doc/computation/fluid.rst index ea6f0569..bec587a4 100644 --- a/doc/computation/fluid.rst +++ b/doc/computation/fluid.rst @@ -85,8 +85,7 @@ Ellipsoid model :figwidth: 50% :align: right - The flight-capable Drosophila Melanogaster model in this figure will be described in a - forthcoming publication. + The flight-capable Drosophila Melanogaster model in this figure is described in :cite:t:`Vaxenburg2024`. In this section we describe and derive a stateless model of the forces exerted onto a moving rigid body by the @@ -94,7 +93,6 @@ surrounding fluid, based on an ellipsoidal approximation of geom shape. This mod different types of fluid forces than the inertia-based model of the previous section. The motivating use-case for this model is insect flight, see figure on the right. - Summary ~~~~~~~ diff --git a/doc/references.bib b/doc/references.bib index e827bad7..71a3432d 100644 --- a/doc/references.bib +++ b/doc/references.bib @@ -88,3 +88,14 @@ year={2015}, publisher={Nature Publishing Group} } + +@article {Vaxenburg2024, + author = {Roman Vaxenburg and Igor Siwanowicz and Josh Merel and Alice A Robie and Carmen Morrow and Guido Novati and Zinovia Stefanidi and Gwyneth M Card and Michael B Reiser and Matthew M Botvinick and Kristin M Branson and Yuval Tassa and Srinivas C Turaga}, + title = {Whole-body simulation of realistic fruit fly locomotion with deep reinforcement learning}, + elocation-id = {2024.03.11.584515}, + year = {2024}, + doi = {10.1101/2024.03.11.584515}, + publisher = {Cold Spring Harbor Laboratory}, + + journal = {bioRxiv} +} From c42868a91b923f8d65f5097693ffe4806eabd50a Mon Sep 17 00:00:00 2001 From: Kyle Bayes Date: Fri, 15 Mar 2024 08:29:39 -0700 Subject: [PATCH 08/51] Update logic for OS filesystem timestamps for caching. PiperOrigin-RevId: 616138153 Change-Id: I0ce966546bc4af04e57b983e27bbd75a94377237 --- src/engine/engine_resource.c | 31 ++++++++++++--------------- test/engine/engine_resource_test.cc | 33 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/engine/engine_resource.c b/src/engine/engine_resource.c index 79a6a9b4..107bf3b4 100644 --- a/src/engine/engine_resource.c +++ b/src/engine/engine_resource.c @@ -34,6 +34,7 @@ #include #include "engine/engine_plugin.h" #include "engine/engine_util_errmem.h" +#include "engine/engine_util_misc.h" // internal helper for mju_fileToMemory (closes fp automatically) static void* _fileToMemory(FILE* fp, const char* filename, size_t* filesize); @@ -113,10 +114,8 @@ mjResource* mju_openResource(const char* name, char* error, size_t error_sz) { memcpy(&spec->mtime, &file_stat.st_mtime, sizeof(time_t)); } else { memset(&spec->mtime, 0, sizeof(time_t)); - resource->timestamp[0] = '\0'; } - strftime(resource->timestamp, 512, "%Y-%m-%d-%H:%M:%S", - localtime(&(spec->mtime))); + mju_encodeBase64(resource->timestamp, (uint8_t*) &spec->mtime, sizeof(time_t)); return resource; } @@ -199,19 +198,6 @@ void mju_getResourceDir(mjResource* resource, const char** dir, int* ndir) { -// modified callback for OS filesystem -static int mju_isModifiedFile(const char* name, const file_spec* spec) { - if (spec != NULL) { - struct stat file_stat; - if (stat(name, &file_stat) == 0) { - return difftime(spec->mtime, file_stat.st_mtime) < 0; - } - } - return 1; // modified (default) -} - - - // return 0 if the resource's timestamp matches the provided timestamp // return > 0 if the the resource is younger than the given timestamp // return < 0 if the resource is older than the given timestamp @@ -224,7 +210,18 @@ int mju_isModifiedResource(const mjResource* resource, const char* timestamp) { return 1; // default (modified) } - return mju_isModifiedFile(resource->name, (file_spec*) resource->data); + // fallback to OS filesystem + if (mju_isValidBase64(timestamp) != sizeof(time_t)) { + return 1; // error (assume modified) + } + + time_t time1, time2; + mju_decodeBase64((uint8_t*) &time1, timestamp); + time2 = ((file_spec*) resource->data)->mtime; + double diff = difftime(time2, time1); + if (diff < 0) return -1; + if (diff > 0) return 1; + return 0; } diff --git a/test/engine/engine_resource_test.cc b/test/engine/engine_resource_test.cc index 07390b63..aba5f585 100644 --- a/test/engine/engine_resource_test.cc +++ b/test/engine/engine_resource_test.cc @@ -15,7 +15,10 @@ // Tests for engine/engine_resource.c #include +#include #include +#include +#include #include #include @@ -24,6 +27,7 @@ #include #include "src/engine/engine_plugin.h" #include "src/engine/engine_resource.h" +#include "src/engine/engine_util_misc.h" #include "test/fixture.h" namespace mujoco { @@ -327,5 +331,34 @@ TEST_F(ResourceTest, NameWithInvalidPrefix) { ASSERT_THAT(resource, IsNull()); } +TEST_F(ResourceTest, OSFilesystemTimestamps) { + time_t t; + + // some random file + const char* const file = "engine/testdata/collision_box/boxbox_deep.xml"; + const std::string xml_path = GetTestDataFilePath(file); + + mjResource* resource = mju_openResource(xml_path.c_str(), nullptr, 0); + mju_decodeBase64((uint8_t*) &t, resource->timestamp); + + // equal timestamps + EXPECT_EQ(mju_isModifiedResource(resource, resource->timestamp), 0); + + std::array test_timestamp; + + // older resource timestamp + t++; + mju_encodeBase64(test_timestamp.data(), (uint8_t*) &t, sizeof(time_t)); + EXPECT_EQ(mju_isModifiedResource(resource, test_timestamp.data()), -1); + + + // newer resource timestamp + t -= 2; + mju_encodeBase64(test_timestamp.data(), (uint8_t*) &t, sizeof(time_t)); + EXPECT_EQ(mju_isModifiedResource(resource, test_timestamp.data()), 1); + + mju_closeResource(resource); +} + } // namespace } // namespace mujoco From c7a8b104f923cf5f93cc8d0e7e541b8f264ab05a Mon Sep 17 00:00:00 2001 From: Kyle Bayes Date: Fri, 15 Mar 2024 09:22:25 -0700 Subject: [PATCH 09/51] Add modified callback for VFS resource provider. PiperOrigin-RevId: 616152275 Change-Id: I417f9b204eaa1eb9fc68a15927f86031dcd20575 --- src/engine/engine_vfs.c | 25 ++++++++++++++++++++++++- test/engine/engine_vfs_test.cc | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/engine/engine_vfs.c b/src/engine/engine_vfs.c index aa8924bc..f6afa0c6 100644 --- a/src/engine/engine_vfs.c +++ b/src/engine/engine_vfs.c @@ -347,6 +347,29 @@ static void vfs_getdir_callback(mjResource* resource, const char** dir, int* ndi } +// modified callback for the VFS resource provider +// return > 0 if modified and 0 if unmodified +static int vfs_modified_callback(const mjResource* resource, const char* timestamp) { + uint64_t filestamp; + if (mju_isValidBase64(timestamp) > sizeof(uint64_t)) { + return 2; // error (assume modified) + } + + mju_decodeBase64((uint8_t*) &filestamp, timestamp); + if (!filestamp) return 3; // no hash (assume modified) + + if (resource) { + const mjVFS* vfs = (const mjVFS*) resource->data; + int i = mj_findFileVFS(vfs, resource->name); + if (i < 0) return 4; // missing file (assume modified) + if (!vfs->filestamp[i]) return 5; // missing filestamp (assume modified) + + if (vfs->filestamp[i] == filestamp) { + return 0; // unmodified + } + } + return 1; // modified +} // open VFS resource mjResource* mju_openVfsResource(const char* name, const mjVFS* vfs) { @@ -362,7 +385,7 @@ mjResource* mju_openVfsResource(const char* name, const mjVFS* vfs) { .read = &vfs_read_callback, .close = &vfs_close_callback, .getdir = &vfs_getdir_callback, - .modified = NULL + .modified = &vfs_modified_callback, }; // create resource diff --git a/test/engine/engine_vfs_test.cc b/test/engine/engine_vfs_test.cc index 93249055..fdc0cbdf 100644 --- a/test/engine/engine_vfs_test.cc +++ b/test/engine/engine_vfs_test.cc @@ -20,6 +20,8 @@ #include #include #include +#include "src/engine/engine_resource.h" +#include "src/engine/engine_vfs.h" #include "test/fixture.h" namespace mujoco { @@ -28,7 +30,7 @@ namespace { using ::testing::NotNull; using EngineVfsTest = MujocoTest; -TEST_F(EngineVfsTest, AddFileTest) { +TEST_F(EngineVfsTest, AddFile) { constexpr char path[] = "engine/testdata/actuation/"; const std::string dir = GetTestDataFilePath(path); std::string file1 = "activation.xml"; @@ -81,7 +83,7 @@ TEST_F(EngineVfsTest, AddFileTest) { mj_deleteVFS(vfs.get()); } -TEST_F(EngineVfsTest, AddBufferTest) { +TEST_F(EngineVfsTest, AddBuffer) { auto vfs = std::make_unique(); mj_defaultVFS(vfs.get()); std::string buffer = ""; @@ -94,5 +96,32 @@ TEST_F(EngineVfsTest, AddBufferTest) { mj_deleteVFS(vfs.get()); } +TEST_F(EngineVfsTest, Timestamps) { + static constexpr char cube[] = R"( + v -0.500000 -0.500000 0.500000 + v 0.500000 -0.500000 0.500000 + v -0.500000 0.500000 0.500000 + v 0.500000 0.500000 0.500000 + v -0.500000 0.500000 -0.500000 + v 0.500000 0.500000 -0.500000 + v -0.500000 -0.500000 -0.500000 + v 0.500000 -0.500000 -0.500000)"; + + auto vfs = std::make_unique(); + mj_defaultVFS(vfs.get()); + mj_addBufferVFS(vfs.get(), "cube.obj", cube, sizeof(cube)); + + mjResource* resource = mju_openVfsResource("cube.obj", vfs.get()); + + // same timestamps + EXPECT_EQ(mju_isModifiedResource(resource, resource->timestamp), 0); + + // different timestamps + EXPECT_EQ(mju_isModifiedResource(resource, "QQ=="), 1); + + mju_closeResource(resource); + mj_deleteVFS(vfs.get()); +} + } // namespace } // namespace mujoco From c5aa22b177676928e5f1d7ffdcc2195657fe472c Mon Sep 17 00:00:00 2001 From: Nimrod Gileadi Date: Fri, 15 Mar 2024 09:23:49 -0700 Subject: [PATCH 10/51] Speed up MakeBVH. 1. Avoid creating unnecessary temporary vectors for the left and right sides of the recursive call, since std::nth_element already splits the array in the right way. 2. Filter contype and conaffinity before calling MakeBVH. This only affects the top level of the MakeBVH recursion. 3. Avoid repeatedly computing mju_rotVecQuat for each element at each nesting level. This is roughly a 2x speedup. PiperOrigin-RevId: 616152673 Change-Id: I6ce7d99cd4a923c43156beb3f2493c649602260e --- src/user/user_objects.cc | 135 +++++++++++++-------------------------- src/user/user_objects.h | 25 +++++++- 2 files changed, 67 insertions(+), 93 deletions(-) diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index db38cad3..dd21fab0 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -292,43 +292,48 @@ mjCBoundingVolume* mjCBoundingVolumeHierarchy::GetBoundingVolume(int id) { // create bounding volume hierarchy void mjCBoundingVolumeHierarchy::CreateBVH() { - std::vector elements(bvleaf_.size()); - for (int i=0; i elements; + elements.reserve(bvleaf_.size()); + mjtNum qinv[4] = {iquat_[0], -iquat_[1], -iquat_[2], -iquat_[3]}; + for (int i = 0; i < bvleaf_.size(); i++) { + if (bvleaf_[i].conaffinity || bvleaf_[i].contype) { + BVElement element; + element.e = &bvleaf_[i]; + element.index = i; + mjtNum vert[3] = {element.e->pos[0] - ipos_[0], + element.e->pos[1] - ipos_[1], + element.e->pos[2] - ipos_[2]}; + mju_rotVecQuat(element.lpos, vert, qinv); + elements.push_back(std::move(element)); + } } - MakeBVH(elements); + MakeBVH(elements.begin(), elements.end()); } - // compute bounding volume hierarchy -int mjCBoundingVolumeHierarchy::MakeBVH(std::vector& elements, int lev) { - if (elements.empty()) { +int mjCBoundingVolumeHierarchy::MakeBVH( + std::vector::iterator elements_begin, + std::vector::iterator elements_end, int lev) { + int nelements = elements_end - elements_begin; + if (nelements == 0) { return -1; } - - bool is_visual = true; - int nelements = elements.size(); mjtNum AAMM[6] = {mjMAXVAL, mjMAXVAL, mjMAXVAL, -mjMAXVAL, -mjMAXVAL, -mjMAXVAL}; // inverse transformation mjtNum qinv[4] = {iquat_[0], -iquat_[1], -iquat_[2], -iquat_[3]}; // accumulate AAMM over elements - for (int i=0; iconaffinity==0 && elements[i]->contype==0) { - continue; - } else { - is_visual = false; - } - + for (auto element = elements_begin; element != elements_end; ++element) { // transform element aabb to aamm format - mjtNum aamm[6] = {elements[i]->aabb[0] - elements[i]->aabb[3], - elements[i]->aabb[1] - elements[i]->aabb[4], - elements[i]->aabb[2] - elements[i]->aabb[5], - elements[i]->aabb[0] + elements[i]->aabb[3], - elements[i]->aabb[1] + elements[i]->aabb[4], - elements[i]->aabb[2] + elements[i]->aabb[5]}; + mjtNum aamm[6] = {element->e->aabb[0] - element->e->aabb[3], + element->e->aabb[1] - element->e->aabb[4], + element->e->aabb[2] - element->e->aabb[5], + element->e->aabb[0] + element->e->aabb[3], + element->e->aabb[1] + element->e->aabb[4], + element->e->aabb[2] + element->e->aabb[5]}; // update node AAMM for (int v=0; v<8; v++) { @@ -338,11 +343,11 @@ int mjCBoundingVolumeHierarchy::MakeBVH(std::vector& e vert[2] = (v&4 ? aamm[5] : aamm[2]); // rotate to the body inertial frame if specified - if (elements[i]->quat) { - mju_rotVecQuat(box, vert, elements[i]->quat); - box[0] += elements[i]->pos[0] - ipos_[0]; - box[1] += elements[i]->pos[1] - ipos_[1]; - box[2] += elements[i]->pos[2] - ipos_[2]; + if (element->e->quat) { + mju_rotVecQuat(box, vert, element->e->quat); + box[0] += element->e->pos[0] - ipos_[0]; + box[1] += element->e->pos[1] - ipos_[1]; + box[2] += element->e->pos[2] - ipos_[2]; mju_rotVecQuat(vert, box, qinv); } @@ -355,11 +360,6 @@ int mjCBoundingVolumeHierarchy::MakeBVH(std::vector& e } } - // a body with only visual geoms does not have a bvh - if (is_visual) { - return nbvh; - } - // inflate flat AABBs for (int i=0; i<3; i++) { if (mju_abs(AAMM[i]-AAMM[i+3])& e for (int i=0; i<2; i++) { child[2*index+i] = -1; } - nodeid[index] = (int*)elements[0]->GetId(); + nodeid[index] = (int*)elements_begin->e->GetId(); return index; } @@ -398,66 +398,23 @@ int mjCBoundingVolumeHierarchy::MakeBVH(std::vector& e axis = edges[axis] > edges[2] ? axis : 2; // find median along the axis - std::vector pos(nelements); - - for (int i=0; ipos[0] - ipos_[0], - elements[i]->pos[1] - ipos_[1], - elements[i]->pos[2] - ipos_[2]}; - mjtNum lpos[3]; - mju_rotVecQuat(lpos, vert, qinv); - pos[i] = lpos[axis]; - } - - auto m = pos.size()/2; - std::nth_element(pos.begin(), pos.begin() + m, pos.end()); - mjtNum threshold = pos[m]; - - // split using median - std::vector left; - std::vector right; - int skipped = 0; - - for (int i=0; ipos[0] - ipos_[0], - elements[i]->pos[1] - ipos_[1], - elements[i]->pos[2] - ipos_[2]}; - mjtNum lpos[3]; - mju_rotVecQuat(lpos, vert, qinv); - - // skip visual objects - if (elements[i]->conaffinity==0 && elements[i]->contype==0) { - skipped++; - continue; - } - if (lpos[axis] < threshold) { - left.push_back(elements[i]); - } else if (lpos[axis] > threshold) { - right.push_back(elements[i]); - } else { - if (left.size() < right.size()) left.push_back(elements[i]); - else right.push_back(elements[i]); - } - } + auto m = nelements/2; + // Note: nth element performs a partial sort of elements + BVElementCompare compare; + compare.axis = axis; + std::nth_element(elements_begin, elements_begin + m, elements_end, compare); // recursive calls - if (!left.empty()) { - child[2*index+0] = MakeBVH(left, lev+1); + if (m > 0) { + child[2*index+0] = MakeBVH(elements_begin, elements_begin + m, lev+1); } - if (!right.empty()) { - child[2*index+1] = MakeBVH(right, lev+1); + if (m != nelements) { + child[2*index+1] = MakeBVH(elements_begin + m, elements_end, lev+1); } // SHOULD NOT OCCUR - if (left.size()+right.size()+skipped != nelements) { - mju_error("some elements were lost, body=%s parent=%d children=%lu", - name_.c_str(), nelements, left.size()+right.size()+skipped); - } - - if (child[2*index+0]==-1 && child[2*index+1]==-1 && !skipped) { + if (child[2*index+0]==-1 && child[2*index+1]==-1) { mju_error("this should have been a leaf, body=%s nelements=%d", name_.c_str(), nelements); } @@ -469,8 +426,6 @@ int mjCBoundingVolumeHierarchy::MakeBVH(std::vector& e return index; } - - //------------------------- class mjCDef implementation -------------------------------------------- // constructor diff --git a/src/user/user_objects.h b/src/user/user_objects.h index 988a084d..2d24ea85 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -15,10 +15,8 @@ #ifndef MUJOCO_SRC_USER_USER_OBJECTS_H_ #define MUJOCO_SRC_USER_USER_OBJECTS_H_ -#include #include #include -#include #include #include #include @@ -144,7 +142,28 @@ class mjCBoundingVolumeHierarchy : public mjCBoundingVolumeHierarchy_ { mjCBoundingVolume* GetBoundingVolume(int id); private: - int MakeBVH(std::vector& elements, int lev = 0); + // internal class used during BVH construction, for partial sorting of bounding volumes + struct BVElement { + const mjCBoundingVolume* e; + // index of the element in the original input to BVH, used to ensure a stable sort + int index; + // position of the element in the BVH axes + mjtNum lpos[3]; + }; + + struct BVElementCompare { + int axis = 0; + + bool operator()(const BVElement& e1, const BVElement& e2) const { + if (e1.lpos[axis] != e2.lpos[axis]) { + return e1.lpos[axis] < e2.lpos[axis]; + } + return e1.index < e2.index; + } + }; + + int MakeBVH(std::vector::iterator elements_begin, + std::vector::iterator elements_end, int lev = 0); }; From bf66801bc98828bbb4bd17d21d2338463d375315 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Fri, 15 Mar 2024 11:09:09 -0700 Subject: [PATCH 11/51] Move printing of model BVH data to the end, make it more compact. PiperOrigin-RevId: 616186922 Change-Id: Id6368a5efd831698f182fe97251b9608312c663c --- src/engine/engine_print.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/engine/engine_print.c b/src/engine/engine_print.c index 4ae6df4a..e14bf591 100644 --- a/src/engine/engine_print.c +++ b/src/engine/engine_print.c @@ -361,14 +361,6 @@ void mj_printFormattedModel(const mjModel* m, const char* filename, const char* } if (m->nbody) fprintf(fp, "\n"); - // BVHs - for (int i=0; i < m->nbvh; i++) { - fprintf(fp, "\nBVH %d:\n", i); - object_class = &m->nbvh; - MJMODEL_POINTERS - } - if (m->nbvh) fprintf(fp, "\n"); - // joints for (int i=0; i < m->njnt; i++) { fprintf(fp, "\nJOINT %d:\n", i); @@ -732,6 +724,15 @@ void mj_printFormattedModel(const mjModel* m, const char* filename, const char* #undef X + // BVHs + fprintf(fp, "BVH:\n"); + fprintf(fp, " %-8s%-8s%-8s%-10s%-s\n","id", "depth", "nodeid", "child[0]" ,"child[1]"); + for (int i=0; i < m->nbvh; i++) { + fprintf(fp, " %-8d%-8d% -8d% -10d% -d\n", + i, m->bvh_depth[i], m->bvh_nodeid[i], m->bvh_child[2*i], m->bvh_child[2*i+1]); + } + fprintf(fp, "\n"); + if (filename) { fclose(fp); } From 74d3d8cb4efbaf3f8d5cb8b8334beabb61bca552 Mon Sep 17 00:00:00 2001 From: Kyle Bayes Date: Fri, 15 Mar 2024 12:30:51 -0700 Subject: [PATCH 12/51] Cache OBJ files in MuJoCo compiler. PiperOrigin-RevId: 616211896 Change-Id: I3b765f4529957914e6154f0e62ef36fd9df93c96 --- src/user/CMakeLists.txt | 2 + src/user/user_api.cc | 19 +++++- src/user/user_api.h | 10 +++ src/user/user_cache.cc | 3 +- src/user/user_cache.h | 35 +++++------ src/user/user_mesh.cc | 122 +++++++++++++++++++++++++++++++++++++ src/user/user_objects.h | 2 + test/user/user_api_test.cc | 54 ++++++++++++++++ 8 files changed, 227 insertions(+), 20 deletions(-) diff --git a/src/user/CMakeLists.txt b/src/user/CMakeLists.txt index 035ef1fe..5aa8981c 100644 --- a/src/user/CMakeLists.txt +++ b/src/user/CMakeLists.txt @@ -15,6 +15,8 @@ set(MUJOCO_USER_SRCS user_api.cc user_api.h + user_cache.cc + user_cache.h user_composite.cc user_composite.h user_flexcomp.cc diff --git a/src/user/user_api.cc b/src/user/user_api.cc index 6f779b4c..8068b1a0 100644 --- a/src/user/user_api.cc +++ b/src/user/user_api.cc @@ -13,8 +13,11 @@ // limitations under the License. #include "user/user_api.h" + +#include #include #include +#include #include #include #include @@ -22,10 +25,9 @@ #include #include "user/user_model.h" #include "user/user_objects.h" +#include "user/user_cache.h" #include "xml/xml_util.h" - - // create model mjSpec* mjm_createSpec() { mjCModel* modelC = new mjCModel; @@ -600,4 +602,17 @@ const char* mjm_setFullInertia(mjmBody* bodyspec, double quat[4], double inertia return body->FullInertia(quat, inertia); } +// -------------------------- GLOBAL ASSET CACHE ------------------------------- +void mj_setCacheSize(mjCache cache, std::size_t size) { + mjCCache* ccache = reinterpret_cast(cache); + if (ccache) { + ccache->SetMaxSize(size); + } +} + + + +mjCache mj_globalCache() { + return NULL; // currently disabled +} diff --git a/src/user/user_api.h b/src/user/user_api.h index 47b2541b..ce164cc3 100644 --- a/src/user/user_api.h +++ b/src/user/user_api.h @@ -983,6 +983,16 @@ MJAPI void mjm_defaultKey(mjmKey& key); // Default plugin attributes. MJAPI void mjm_defaultPlugin(mjmPlugin& plugin); +//------------------------- Cache functions ------------------------------------ + +typedef struct _mjCache* mjCache; + +// Set the size of the cache in bytes. +MJAPI void mj_setCacheSize(mjCache cache, size_t size); + +// Get internal global cache context. +MJAPI mjCache mj_globalCache(); + #ifdef __cplusplus } #endif diff --git a/src/user/user_cache.cc b/src/user/user_cache.cc index 64d1c9dd..64f125fc 100644 --- a/src/user/user_cache.cc +++ b/src/user/user_cache.cc @@ -39,7 +39,8 @@ template std::size_t mjCAsset::Add(const std::string& name, const uint8_t* ptr = reinterpret_cast(data); mjCAssetData& block = it->second; - block.bytes = std::make_shared(nbytes); + block.bytes = std::shared_ptr(new uint8_t[nbytes], + [](uint8_t *p) {delete [] p;}); std::copy(ptr, ptr + nbytes, block.bytes.get()); block.nbytes = nbytes; nbytes_ += nbytes; diff --git a/src/user/user_cache.h b/src/user/user_cache.h index ee0f1ef1..62af3580 100644 --- a/src/user/user_cache.h +++ b/src/user/user_cache.h @@ -30,7 +30,7 @@ // data associated with an asset struct mjCAssetData { - std::shared_ptr bytes; // raw serialized bytes of cached data + std::shared_ptr bytes; // raw serialized bytes of cached data std::size_t nbytes; // number of bytes stored }; @@ -80,6 +80,11 @@ class mjCAsset { return blocks_.find(name) != blocks_.end(); } + const std::string& Timestamp() const { return timestamp_; } + const std::string& Id() const { return id_; } + std::size_t InsertNum() const { return insert_num_; } + std::size_t AccessCount() const { return access_count_; } + private: mjCAsset() = default; @@ -105,10 +110,6 @@ class mjCAsset { void SetTimestamp(std::string timestamp) { timestamp_ = timestamp; } // accessors - const std::string& Id() const { return id_; } - const std::string& Timestamp() const { return timestamp_; } - std::size_t InsertNum() const { return insert_num_; } - std::size_t AccessCount() const { return access_count_; } std::size_t BytesCount() const { return nbytes_; } const std::unordered_map& Blocks() const { return blocks_; @@ -128,14 +129,23 @@ class mjCAsset { std::set references_; }; +struct mjCAssetCompare { + bool operator()(const mjCAsset* e1, const mjCAsset* e2) const { + if (e1->AccessCount() != e2->AccessCount()) { + return e1->AccessCount() < e2->AccessCount(); + } + return e1->InsertNum() < e2->InsertNum(); + } +}; + // the class container for a thread-safe asset cache class mjCCache { public: explicit mjCCache(std::size_t size) : max_size_(size) {} // move only - mjCCache(mjCCache&& other) = default; - mjCCache& operator=(mjCCache&& other) = default; + mjCCache(mjCCache&& other) = delete; + mjCCache& operator=(mjCCache&& other) = delete; mjCCache(const mjCCache& other) = delete; mjCCache& operator=(const mjCCache& other) = delete; @@ -186,20 +196,11 @@ class mjCCache { std::size_t size_ = 0; // current size of the cache in bytes std::size_t max_size_ = 0; // max size of the cache in bytes - // compare function for the priority queue - static constexpr auto compare_ = [](const mjCAsset* e1, - const mjCAsset* e2) { - if (e1->AccessCount() != e2->AccessCount()) { - return e1->AccessCount() < e2->AccessCount(); - } - return e1->InsertNum() < e2->InsertNum(); - }; - // internal constant look up table for assets std::unordered_map lookup_; // internal priority queue for the cache - std::set entries_; + std::set entries_; // models using the cache along with the assets they reference std::unordered_map> models_; diff --git a/src/user/user_mesh.cc b/src/user/user_mesh.cc index 552cdb62..e678cbec 100644 --- a/src/user/user_mesh.cc +++ b/src/user/user_mesh.cc @@ -60,6 +60,7 @@ #include "engine/engine_util_misc.h" #include "engine/engine_util_solve.h" #include "engine/engine_util_spatial.h" +#include "user/user_cache.h" #include "user/user_model.h" #include "user/user_objects.h" #include "user/user_util.h" @@ -967,6 +968,19 @@ void mjCMesh::RemoveRepeated() { void mjCMesh::LoadOBJ(mjResource* resource) { tinyobj::ObjReader objReader; const void* bytes = nullptr; + + // try loading from cache + mjCCache *cache = reinterpret_cast(mj_globalCache()); + if (cache) { + auto asset = cache->Get(resource->name); + if (asset.has_value() && + !mju_isModifiedResource(resource, asset->Timestamp().c_str())) { + if (LoadCachedOBJ(asset.value())) { + return; + } + } + } + int buffer_sz = mju_readResource(resource, &bytes); if (buffer_sz < 0) { throw mjCError(this, "could not read OBJ file '%s'", resource->name); @@ -1030,9 +1044,117 @@ void mjCMesh::LoadOBJ(mjResource* resource) { for (int i=0; iname, resource->timestamp); + + asset.AddVector("uservert_", uservert_); + asset.AddVector("usernormal_", usernormal_); + asset.AddVector("usertexcoord_", usertexcoord_); + + if (!objReader.GetShapes().empty()) { + const auto& mesh = objReader.GetShapes()[0].mesh; + std::vector vertex_index; + vertex_index.reserve(mesh.indices.size()); + + std::vector normal_index; + normal_index.reserve(mesh.indices.size()); + + std::vector texcoord_index; + texcoord_index.reserve(mesh.indices.size()); + + for (tinyobj::index_t index : mesh.indices) { + vertex_index.push_back(index.vertex_index); + normal_index.push_back(index.normal_index); + texcoord_index.push_back(index.texcoord_index); + } + + asset.AddVector("num_face_vertices", mesh.num_face_vertices); + asset.AddVector("vertex_index", vertex_index); + asset.AddVector("normal_index", normal_index); + asset.AddVector("texcoord_index", texcoord_index); + } else { + asset.AddVector("num_face_vertices", std::vector()); + asset.AddVector("vertex_index", std::vector()); + asset.AddVector("normal_index", std::vector()); + asset.AddVector("texcoord_index", std::vector()); + } + cache->Insert(std::move(asset)); + } } + +// load OBJ from cached asset, return true on success +bool mjCMesh::LoadCachedOBJ(const mjCAsset& asset) { + // check that asset has all data + if (!asset.HasData("uservert_") || !asset.HasData("usernormal_") + || !asset.HasData("usertexcoord_") || !asset.HasData("num_face_vertices") + || !asset.HasData("vertex_index") || !asset.HasData("normal_index") + || !asset.HasData("texcoord_index")) { + return false; + } + uservert_ = asset.GetVector("uservert_").value(); + usernormal_ = asset.GetVector("usernormal_").value(); + usertexcoord_ = asset.GetVector("usertexcoord_").value(); + + vector vertex_index = asset.GetVector("vertex_index").value(); + vector normal_index = asset.GetVector("normal_index").value(); + vector texcoord_index = asset.GetVector("texcoord_index").value(); + vector num_face_vertices = + asset.GetVector("num_face_vertices").value(); + + bool righthand = (scale[0] * scale[1] * scale[2]) > 0; + + + for (int face = 0, i = 0; i < vertex_index.size();) { + int nfacevert = num_face_vertices[face]; + if (nfacevert < 3 || nfacevert > 4) { + throw mjCError( + this, "only tri or quad meshes are supported for OBJ (file '%s')", + asset.Id().c_str()); + } + + userface_.push_back(vertex_index[i]); + userface_.push_back(vertex_index[i + (righthand == 1 ? 1 : 2)]); + userface_.push_back(vertex_index[i + (righthand == 1 ? 2 : 1)]); + + if (!usernormal_.empty()) { + userfacenormal_.push_back(normal_index[i]); + userfacenormal_.push_back(normal_index[i + (righthand == 1 ? 1 : 2)]); + userfacenormal_.push_back(normal_index[i + (righthand == 1 ? 2 : 1)]); + } + + if (!usertexcoord_.empty()) { + userfacetexcoord_.push_back(texcoord_index[i]); + userfacetexcoord_.push_back(texcoord_index[i + (righthand == 1 ? 1 : 2)]); + userfacetexcoord_.push_back(texcoord_index[i + (righthand == 1 ? 2 : 1)]); + } + + if (nfacevert == 4) { + userface_.push_back(vertex_index[i]); + userface_.push_back(vertex_index[i + (righthand == 1 ? 2 : 3)]); + userface_.push_back(vertex_index[i + (righthand == 1 ? 3 : 2)]); + + if (!usernormal_.empty()) { + userfacenormal_.push_back(normal_index[i]); + userfacenormal_.push_back(normal_index[i + (righthand == 1 ? 1 : 2)]); + userfacenormal_.push_back(normal_index[i + (righthand == 1 ? 2 : 1)]); + } + + if (!usertexcoord_.empty()) { + userfacetexcoord_.push_back(texcoord_index[i]); + userfacetexcoord_.push_back(texcoord_index[i + (righthand == 1 ? 1 : 2)]); + userfacetexcoord_.push_back(texcoord_index[i + (righthand == 1 ? 2 : 1)]); + } + } + i += nfacevert; + ++face; + } + return true; +} + // load STL binary mesh void mjCMesh::LoadSTL(mjResource* resource) { bool righthand = (scale[0]*scale[1]*scale[2]>0); diff --git a/src/user/user_objects.h b/src/user/user_objects.h index 2d24ea85..a62436e1 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -26,6 +26,7 @@ #include #include #include "user/user_api.h" +#include "user/user_cache.h" // forward declarations of all mjC/X classes class mjCError; @@ -827,6 +828,7 @@ class mjCMesh: public mjCMesh_, private mjmMesh { private: void LoadOBJ(mjResource* resource); // load mesh in wavefront OBJ format + bool LoadCachedOBJ(const mjCAsset& asset); // load OBJ from cache asset, return true on success void LoadSTL(mjResource* resource); // load mesh in STL BIN format void LoadMSH(mjResource* resource); // load mesh in MSH BIN format void LoadSDF(); // generate mesh using marching cubes diff --git a/test/user/user_api_test.cc b/test/user/user_api_test.cc index acfa8501..926e8dc3 100644 --- a/test/user/user_api_test.cc +++ b/test/user/user_api_test.cc @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -116,5 +117,58 @@ TEST_F(PluginTest, RecompileCompare) { } } +// ------------------- test cache with modified assets ------------------------- +TEST_F(PluginTest, RecompileCompareCache) { + static constexpr char xml[] = R"( + + + + + + + + )"; + + static constexpr char cube1[] = R"( + v -0.500000 -0.500000 0.500000 + v 0.500000 -0.500000 0.500000 + v -0.500000 0.500000 0.500000 + v 0.500000 0.500000 0.500000 + v -0.500000 0.500000 -0.500000 + v 0.500000 0.500000 -0.500000 + v -0.500000 -0.500000 -0.500000 + v 0.500000 -0.500000 -0.500000)"; + + static constexpr char cube2[] = R"( + v -1 -1 1 + v 1 -1 1 + v -1 1 1 + v 1 1 1 + v -1 1 -1 + v 1 1 -1 + v -1 -1 -1 + v 1 -1 -1)"; + + auto vfs = std::make_unique(); + mj_defaultVFS(vfs.get()); + mj_addBufferVFS(vfs.get(), "cube.obj", cube1, sizeof(cube1)); + + std::array error; + + // load model once + mjModel* m = LoadModelFromString(xml, error.data(), error.size(), vfs.get()); + EXPECT_EQ(m->mesh_vert[0], -0.5); + mj_deleteModel(m); + + // update cube.obj, load again + mj_deleteFileVFS(vfs.get(), "cube.obj"); + mj_addBufferVFS(vfs.get(), "cube.obj", cube2, sizeof(cube2)); + m = LoadModelFromString(xml, error.data(), error.size(), vfs.get()); + EXPECT_EQ(m->mesh_vert[0], -1); + mj_deleteModel(m); + + mj_deleteVFS(vfs.get()); +} + } // namespace } // namespace mujoco From e95159b4f6d48d114b16a8dc13ad26b3e44bc3e2 Mon Sep 17 00:00:00 2001 From: Baruch Tabanpour Date: Fri, 15 Mar 2024 13:59:29 -0700 Subject: [PATCH 13/51] Small fix to mjx tutorial. PiperOrigin-RevId: 616235636 Change-Id: I38675c032bdca8f26ab0550896928d097ee86653 --- mjx/tutorial.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mjx/tutorial.ipynb b/mjx/tutorial.ipynb index 65579cad..f57aee4d 100644 --- a/mjx/tutorial.ipynb +++ b/mjx/tutorial.ipynb @@ -367,7 +367,7 @@ "rng = jax.random.split(rng, 4096)\n", "batch = jax.vmap(lambda rng: mjx_data.replace(qpos=jax.random.uniform(rng, (1,))))(rng)\n", "\n", - "jit_step = jax.vmap(mjx.step, in_axes=(None, 0))\n", + "jit_step = jax.jit(jax.vmap(mjx.step, in_axes=(None, 0)))\n", "batch = jit_step(mjx_model, batch)\n", "\n", "print(batch.qpos)" From dd2580e546d5b32b0ef8fbab35c7b7ee0fc17de2 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Mon, 18 Mar 2024 01:42:58 -0700 Subject: [PATCH 14/51] Add internal functions for 3x3 matmul. PiperOrigin-RevId: 616749614 Change-Id: I7f3ac2ffc826076b6c97424324f03ecd9ccd4655 --- src/engine/engine_collision_box.c | 8 ++--- src/engine/engine_collision_convex.c | 4 +-- src/engine/engine_derivative.c | 2 +- src/engine/engine_support.c | 4 +-- src/engine/engine_util_blas.c | 45 ++++++++++++++++++++++++++++ src/engine/engine_util_blas.h | 8 +++++ src/engine/engine_util_solve.c | 4 +-- test/engine/engine_util_blas_test.cc | 33 ++++++++++++++++++++ 8 files changed, 97 insertions(+), 11 deletions(-) diff --git a/src/engine/engine_collision_box.c b/src/engine/engine_collision_box.c index a9c47376..3b1c9d1c 100644 --- a/src/engine/engine_collision_box.c +++ b/src/engine/engine_collision_box.c @@ -638,7 +638,7 @@ int mjc_BoxBox(const mjModel* M, const mjData* D, mjContact* con, int g1, int g2 mju_sub3(tmp1, pos1, pos2); mju_rotVecMatT(pos12, tmp1, mat2); - mju_mulMatTMat(rot, mat1, mat2, 3, 3, 3); + mju_mulMatTMat3(rot, mat1, mat2); mju_transpose(rott, rot, 3, 3); for (i = 0; i < 9; i++) @@ -804,7 +804,7 @@ int mjc_BoxBox(const mjModel* M, const mjData* D, mjContact* con, int g1, int g2 } if (q2) { - mju_mulMatMatT(r, rotmore, rot, 3, 3, 3); + mju_mulMatMatT3(r, rotmore, rot); // mju_rotVecMat(p,pos12,rotmore); // mju_rotVecMat(tmp1,size2,rotmore); @@ -956,7 +956,7 @@ int mjc_BoxBox(const mjModel* M, const mjData* D, mjContact* con, int g1, int g2 } - mju_mulMatMatT(r, q2 ? mat2 : mat1, rotmore, 3, 3, 3); + mju_mulMatMatT3(r, q2 ? mat2 : mat1, rotmore); mju_copy3(p, q2 ? pos2 : pos1); tmp2[0] = (q2 ? -1 : 1) * r[2]; @@ -1319,7 +1319,7 @@ edgeedge: } } - mju_mulMatMatT(r, mat1, rotmore, 3, 3, 3); + mju_mulMatMatT3(r, mat1, rotmore); mju_rotVecMat(tmp1, rnorm, r); diff --git a/src/engine/engine_collision_convex.c b/src/engine/engine_collision_convex.c index 1f526af6..eed233b5 100644 --- a/src/engine/engine_collision_convex.c +++ b/src/engine/engine_collision_convex.c @@ -318,7 +318,7 @@ static void mju_rotateFrame(const mjtNum origin[3], const mjtNum rot[9], mjtNum mat[9], vec[3], rel[3]; // rotate frame: xmat = rot*xmat - mju_mulMatMat(mat, rot, xmat, 3, 3, 3); + mju_mulMatMat3(mat, rot, xmat); mju_copy(xmat, mat, 9); // vector to rotation origin: rel = origin - xpos @@ -682,7 +682,7 @@ int mjc_ConvexHField(const mjModel* m, const mjData* d, } // express geom2 mat in heightfield frame - mju_mulMatTMat(mat, mat1, mat2, 3, 3, 3); + mju_mulMatTMat3(mat, mat1, mat2); //------------------------------------- AABB computation, box-box test diff --git a/src/engine/engine_derivative.c b/src/engine/engine_derivative.c index 643c9b4f..a713baea 100644 --- a/src/engine/engine_derivative.c +++ b/src/engine/engine_derivative.c @@ -251,7 +251,7 @@ void mjd_subQuat(const mjtNum qa[4], const mjtNum qb[4], mjtNum Da[9], mjtNum Db // add term linear in K * K mjtNum KK[9]; - mju_mulMatMat(KK, K, K, 3, 3, 3); + mju_mulMatMat3(KK, K, K); mjtNum coef = 1.0 - (half_angle < 6e-8 ? 1.0 : half_angle / mju_tan(half_angle)); mju_addToScl(Da_tmp, KK, coef, 9); diff --git a/src/engine/engine_support.c b/src/engine/engine_support.c index 87cbb4c6..1090305c 100644 --- a/src/engine/engine_support.c +++ b/src/engine/engine_support.c @@ -815,8 +815,8 @@ void mj_angmomMat(const mjModel* m, mjData* d, mjtNum* mat, int body) { // term1 = body angular momentum about self COM in world frame mjtNum tmp1[9], tmp2[9]; - mju_mulMatMat(tmp1, ximat, inertia, 3, 3, 3); // tmp1 = ximat * inertia - mju_mulMatMatT(tmp2, tmp1, ximat, 3, 3, 3); // tmp2 = ximat * inertia * ximat^T + mju_mulMatMat3(tmp1, ximat, inertia); // tmp1 = ximat * inertia + mju_mulMatMatT3(tmp2, tmp1, ximat); // tmp2 = ximat * inertia * ximat^T mju_mulMatMat(term1, tmp2, jacr, 3, 3, nv); // term1 = ximat * inertia * ximat^T * jacr // location of body COM w.r.t subtree COM diff --git a/src/engine/engine_util_blas.c b/src/engine/engine_util_blas.c index d5eb960a..9120969c 100644 --- a/src/engine/engine_util_blas.c +++ b/src/engine/engine_util_blas.c @@ -180,6 +180,51 @@ void mju_rotVecMatT(mjtNum res[3], const mjtNum vec[3], const mjtNum mat[9]) { +// multiply 3x3 matrices, +void mju_mulMatMat3(mjtNum res[9], const mjtNum a[3], const mjtNum b[9]) { + res[0] = a[0]*b[0] + a[1]*b[3] + a[2]*b[6]; + res[1] = a[0]*b[1] + a[1]*b[4] + a[2]*b[7]; + res[2] = a[0]*b[2] + a[1]*b[5] + a[2]*b[8]; + res[3] = a[3]*b[0] + a[4]*b[3] + a[5]*b[6]; + res[4] = a[3]*b[1] + a[4]*b[4] + a[5]*b[7]; + res[5] = a[3]*b[2] + a[4]*b[5] + a[5]*b[8]; + res[6] = a[6]*b[0] + a[7]*b[3] + a[8]*b[6]; + res[7] = a[6]*b[1] + a[7]*b[4] + a[8]*b[7]; + res[8] = a[6]*b[2] + a[7]*b[5] + a[8]*b[8]; +} + + + +// multiply 3x3 matrices, first argument transposed +void mju_mulMatTMat3(mjtNum res[9], const mjtNum a[3], const mjtNum b[9]) { + res[0] = a[0]*b[0] + a[3]*b[3] + a[6]*b[6]; + res[1] = a[0]*b[1] + a[3]*b[4] + a[6]*b[7]; + res[2] = a[0]*b[2] + a[3]*b[5] + a[6]*b[8]; + res[3] = a[1]*b[0] + a[4]*b[3] + a[7]*b[6]; + res[4] = a[1]*b[1] + a[4]*b[4] + a[7]*b[7]; + res[5] = a[1]*b[2] + a[4]*b[5] + a[7]*b[8]; + res[6] = a[2]*b[0] + a[5]*b[3] + a[8]*b[6]; + res[7] = a[2]*b[1] + a[5]*b[4] + a[8]*b[7]; + res[8] = a[2]*b[2] + a[5]*b[5] + a[8]*b[8]; +} + + + +// multiply 3x3 matrices, second argument transposed +void mju_mulMatMatT3(mjtNum res[9], const mjtNum a[3], const mjtNum b[9]) { + res[0] = a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; + res[1] = a[0]*b[3] + a[1]*b[4] + a[2]*b[5]; + res[2] = a[0]*b[6] + a[1]*b[7] + a[2]*b[8]; + res[3] = a[3]*b[0] + a[4]*b[1] + a[5]*b[2]; + res[4] = a[3]*b[3] + a[4]*b[4] + a[5]*b[5]; + res[5] = a[3]*b[6] + a[4]*b[7] + a[5]*b[8]; + res[6] = a[6]*b[0] + a[7]*b[1] + a[8]*b[2]; + res[7] = a[6]*b[3] + a[7]*b[4] + a[8]*b[5]; + res[8] = a[6]*b[6] + a[7]*b[7] + a[8]*b[8]; +} + + + //------------------------------ 4D vector and matrix-vector operations ---------------------------- // res = 0 diff --git a/src/engine/engine_util_blas.h b/src/engine/engine_util_blas.h index 2b82cb54..96ebbe58 100644 --- a/src/engine/engine_util_blas.h +++ b/src/engine/engine_util_blas.h @@ -109,6 +109,14 @@ MJAPI void mju_rotVecMat(mjtNum res[3], const mjtNum vec[3], const mjtNum mat[9] // multiply vector by transposed 3D rotation matrix MJAPI void mju_rotVecMatT(mjtNum res[3], const mjtNum vec[3], const mjtNum mat[9]); +// multiply 3x3 matrices +MJAPI void mju_mulMatMat3(mjtNum res[9], const mjtNum mat1[3], const mjtNum mat2[9]); + +// multiply 3x3 matrices, first argument transposed +MJAPI void mju_mulMatTMat3(mjtNum res[9], const mjtNum a[3], const mjtNum b[9]); + +// multiply 3x3 matrices, second argument transposed +MJAPI void mju_mulMatMatT3(mjtNum res[9], const mjtNum mat1[3], const mjtNum mat2[9]); //------------------------------ 4D/quaternion operations ------------------------------------------ diff --git a/src/engine/engine_util_solve.c b/src/engine/engine_util_solve.c index 4efba4a8..6b50cbff 100644 --- a/src/engine/engine_util_solve.c +++ b/src/engine/engine_util_solve.c @@ -721,8 +721,8 @@ int mju_eig3(mjtNum eigval[3], mjtNum eigvec[9], mjtNum quat[4], const mjtNum ma for (iter=0; iter < 500; iter++) { // make quaternion matrix eigvec, compute D = eigvec'*mat*eigvec mju_quat2Mat(eigvec, quat); - mju_mulMatTMat(tmp, eigvec, mat, 3, 3, 3); - mju_mulMatMat(D, tmp, eigvec, 3, 3, 3); + mju_mulMatTMat3(tmp, eigvec, mat); + mju_mulMatMat3(D, tmp, eigvec); // assign eigenvalues eigval[0] = D[0]; diff --git a/test/engine/engine_util_blas_test.cc b/test/engine/engine_util_blas_test.cc index 0ae8ff8e..e2d354d9 100644 --- a/test/engine/engine_util_blas_test.cc +++ b/test/engine/engine_util_blas_test.cc @@ -95,5 +95,38 @@ TEST_F(EngineUtilBlasTest, MjuSymmetrize) { 3, 3.5, 3)); } +TEST_F(EngineUtilBlasTest, MjuMulMat3) { + const mjtNum mat1[9] = { + 1, 2, 3, + 4, 5, 6, + 7, 8, 9 + }; + const mjtNum mat2[9] = { + 2, 3, 4, + 5, 6, 7, + 8, 9, 10 + }; + mjtNum res1[9] = {0}; + mjtNum res2[9] = {0}; + + mju_mulMatMat3(res1, mat1, mat2); + mju_mulMatMat(res2, mat1, mat2, 3, 3, 3); + for (int i = 0; i < 9; ++i) { + EXPECT_EQ(res1[i], res2[i]); + } + + mju_mulMatTMat3(res1, mat1, mat2); + mju_mulMatTMat(res2, mat1, mat2, 3, 3, 3); + for (int i = 0; i < 9; ++i) { + EXPECT_EQ(res1[i], res2[i]); + } + + mju_mulMatMatT3(res1, mat1, mat2); + mju_mulMatMatT(res2, mat1, mat2, 3, 3, 3); + for (int i = 0; i < 9; ++i) { + EXPECT_EQ(res1[i], res2[i]); + } +} + } // namespace } // namespace mujoco From 8afcfd0fa1c97e7e6247e4b74386088950474560 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Mon, 18 Mar 2024 01:57:49 -0700 Subject: [PATCH 15/51] Add custom elements to testdata/model.xml PiperOrigin-RevId: 616752352 Change-Id: Iaaee19657e97f4962d9a2fe6e7671f3ce832264a --- test/testdata/model.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/testdata/model.xml b/test/testdata/model.xml index 8f1f16fe..5256859c 100644 --- a/test/testdata/model.xml +++ b/test/testdata/model.xml @@ -161,4 +161,13 @@ qpos="0.0133625 -0.013799 0.659429 0.999776 0.019159 0.00902704 0.000572574 -0.00776575 0.0983289 0.999861 -0.00869796 -0.0141805 0.000912197 0.00700633 0.0930296 0.00637469 -0.00313231 0.119692 0.0051478 -0.0469067 0 -0.500224 0.300659 0.69913 1 -0.000367766 -0.000265698 -0.000109715 -0.319851 0.525628 0.702735 0.29858 0.698263 -0.0490604 -0.648746 -0.579432 0.4206 0.749601 0.900145 -0.208463 0.346664 -0.161576 -0.200033 0.300084 0.976421 0.878429 -0.00171382 0.00127086 -0.477867" qvel="0.508861 -0.243772 -0.327162 0.549686 1.13746 0.0282475 -0.0865243 1.06414 -0.239958 -0.532111 -0.00133789 -0.0654491 0.533148 -0.253161 0.122149 0.824764 0.723529 -0.674175 0 -0.00154509 -0.00568917 0.00479921 0.00541817 0.00115895 0.00317796 -0.160161 -0.599488 -1.38103 14.9789 -1.05454 -13.9252 -0.31223 -0.0102486 -0.405851 5.43992 -4.71514 0.114928 -0.00123758 0.000187845 -0.244109 -0.190199 0.0697975 -16.3286"/> + + + + + + + + + From acaf86a96ff557617e53d0b62b0240272177f086 Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Mon, 18 Mar 2024 05:59:33 -0700 Subject: [PATCH 16/51] Fix input array size in mju_mulMatMat3. PiperOrigin-RevId: 616802192 Change-Id: I4dbc07d392b23a7014331ab850b685c1b82d3dcf --- src/engine/engine_util_blas.c | 6 +++--- src/engine/engine_util_blas.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/engine/engine_util_blas.c b/src/engine/engine_util_blas.c index 9120969c..65c60c8d 100644 --- a/src/engine/engine_util_blas.c +++ b/src/engine/engine_util_blas.c @@ -181,7 +181,7 @@ void mju_rotVecMatT(mjtNum res[3], const mjtNum vec[3], const mjtNum mat[9]) { // multiply 3x3 matrices, -void mju_mulMatMat3(mjtNum res[9], const mjtNum a[3], const mjtNum b[9]) { +void mju_mulMatMat3(mjtNum res[9], const mjtNum a[9], const mjtNum b[9]) { res[0] = a[0]*b[0] + a[1]*b[3] + a[2]*b[6]; res[1] = a[0]*b[1] + a[1]*b[4] + a[2]*b[7]; res[2] = a[0]*b[2] + a[1]*b[5] + a[2]*b[8]; @@ -196,7 +196,7 @@ void mju_mulMatMat3(mjtNum res[9], const mjtNum a[3], const mjtNum b[9]) { // multiply 3x3 matrices, first argument transposed -void mju_mulMatTMat3(mjtNum res[9], const mjtNum a[3], const mjtNum b[9]) { +void mju_mulMatTMat3(mjtNum res[9], const mjtNum a[9], const mjtNum b[9]) { res[0] = a[0]*b[0] + a[3]*b[3] + a[6]*b[6]; res[1] = a[0]*b[1] + a[3]*b[4] + a[6]*b[7]; res[2] = a[0]*b[2] + a[3]*b[5] + a[6]*b[8]; @@ -211,7 +211,7 @@ void mju_mulMatTMat3(mjtNum res[9], const mjtNum a[3], const mjtNum b[9]) { // multiply 3x3 matrices, second argument transposed -void mju_mulMatMatT3(mjtNum res[9], const mjtNum a[3], const mjtNum b[9]) { +void mju_mulMatMatT3(mjtNum res[9], const mjtNum a[9], const mjtNum b[9]) { res[0] = a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; res[1] = a[0]*b[3] + a[1]*b[4] + a[2]*b[5]; res[2] = a[0]*b[6] + a[1]*b[7] + a[2]*b[8]; diff --git a/src/engine/engine_util_blas.h b/src/engine/engine_util_blas.h index 96ebbe58..5bbfcd04 100644 --- a/src/engine/engine_util_blas.h +++ b/src/engine/engine_util_blas.h @@ -110,13 +110,13 @@ MJAPI void mju_rotVecMat(mjtNum res[3], const mjtNum vec[3], const mjtNum mat[9] MJAPI void mju_rotVecMatT(mjtNum res[3], const mjtNum vec[3], const mjtNum mat[9]); // multiply 3x3 matrices -MJAPI void mju_mulMatMat3(mjtNum res[9], const mjtNum mat1[3], const mjtNum mat2[9]); +MJAPI void mju_mulMatMat3(mjtNum res[9], const mjtNum mat1[9], const mjtNum mat2[9]); // multiply 3x3 matrices, first argument transposed -MJAPI void mju_mulMatTMat3(mjtNum res[9], const mjtNum a[3], const mjtNum b[9]); +MJAPI void mju_mulMatTMat3(mjtNum res[9], const mjtNum a[9], const mjtNum b[9]); // multiply 3x3 matrices, second argument transposed -MJAPI void mju_mulMatMatT3(mjtNum res[9], const mjtNum mat1[3], const mjtNum mat2[9]); +MJAPI void mju_mulMatMatT3(mjtNum res[9], const mjtNum mat1[9], const mjtNum mat2[9]); //------------------------------ 4D/quaternion operations ------------------------------------------ From de918a8b2d3114f0416e763928c69823d56c0987 Mon Sep 17 00:00:00 2001 From: Nimrod Gileadi Date: Mon, 18 Mar 2024 06:18:28 -0700 Subject: [PATCH 17/51] Small cosmetic fixes to MakeBVH. Remove the index member of BVElement, since it's redundant for the purpose of sorting. BVElement is now 32 bytes instead of 40, which should make things a bit better, as this data gets moved around during MakeBVH. Unfortunately, this has no measurable effect on the benchmark. PiperOrigin-RevId: 616806520 Change-Id: I3b8a28c42a4a21dc25985e63ac57764fdb669afa --- src/user/user_objects.cc | 5 ++--- src/user/user_objects.h | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index dd21fab0..997bcde4 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -301,7 +301,6 @@ void mjCBoundingVolumeHierarchy::CreateBVH() { if (bvleaf_[i].conaffinity || bvleaf_[i].contype) { BVElement element; element.e = &bvleaf_[i]; - element.index = i; mjtNum vert[3] = {element.e->pos[0] - ipos_[0], element.e->pos[1] - ipos_[1], element.e->pos[2] - ipos_[2]}; @@ -398,10 +397,10 @@ int mjCBoundingVolumeHierarchy::MakeBVH( axis = edges[axis] > edges[2] ? axis : 2; // find median along the axis - auto m = nelements/2; - // Note: nth element performs a partial sort of elements + // note: nth_element performs a partial sort of elements BVElementCompare compare; compare.axis = axis; + int m = nelements / 2; std::nth_element(elements_begin, elements_begin + m, elements_end, compare); // recursive calls diff --git a/src/user/user_objects.h b/src/user/user_objects.h index a62436e1..01333478 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -146,8 +146,6 @@ class mjCBoundingVolumeHierarchy : public mjCBoundingVolumeHierarchy_ { // internal class used during BVH construction, for partial sorting of bounding volumes struct BVElement { const mjCBoundingVolume* e; - // index of the element in the original input to BVH, used to ensure a stable sort - int index; // position of the element in the BVH axes mjtNum lpos[3]; }; @@ -159,7 +157,8 @@ class mjCBoundingVolumeHierarchy : public mjCBoundingVolumeHierarchy_ { if (e1.lpos[axis] != e2.lpos[axis]) { return e1.lpos[axis] < e2.lpos[axis]; } - return e1.index < e2.index; + // comparing pointers gives a stable sort, because they both come from the same array + return e1.e < e2.e; } }; From 372aa021d09a4fbf80acf704eae53479b18c18d4 Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Mon, 18 Mar 2024 09:24:36 -0700 Subject: [PATCH 18/51] Add copy constructor and assignment to mjCModel. PiperOrigin-RevId: 616850780 Change-Id: I7fedab2efa2a90fd7ce952eac4e195f77c5ff5bc --- src/user/user_api.cc | 8 + src/user/user_api.h | 3 + src/user/user_mesh.cc | 39 ++++ src/user/user_model.cc | 197 ++++++++++++++-- src/user/user_model.h | 309 +++++++++++++------------ src/user/user_objects.cc | 460 ++++++++++++++++++++++++++----------- src/user/user_objects.h | 26 ++- test/user/user_api_test.cc | 57 +++-- 8 files changed, 766 insertions(+), 333 deletions(-) diff --git a/src/user/user_api.cc b/src/user/user_api.cc index 8068b1a0..f14e75e3 100644 --- a/src/user/user_api.cc +++ b/src/user/user_api.cc @@ -36,6 +36,14 @@ mjSpec* mjm_createSpec() { +// copy model +mjSpec* mjm_copySpec(const mjSpec* s) { + mjCModel* modelC = new mjCModel(*reinterpret_cast(s->element)); + return &modelC->spec; +} + + + // copy back model void mjm_copyBack(mjSpec* s, const mjModel* m) { mjCModel* modelC = reinterpret_cast(s->element); diff --git a/src/user/user_api.h b/src/user/user_api.h index ce164cc3..d5ffb06b 100644 --- a/src/user/user_api.h +++ b/src/user/user_api.h @@ -731,6 +731,9 @@ typedef struct _mjmDefault { // default specification // Create model. MJAPI mjSpec* mjm_createSpec(); +// Copy model. +MJAPI mjSpec* mjm_copySpec(const mjSpec* s); + // Copy back model. MJAPI void mjm_copyBack(mjSpec* s, const mjModel* m); diff --git a/src/user/user_mesh.cc b/src/user/user_mesh.cc index e678cbec..59aad976 100644 --- a/src/user/user_mesh.cc +++ b/src/user/user_mesh.cc @@ -200,41 +200,62 @@ mjCMesh& mjCMesh::operator=(const mjCMesh& other) { size_t nvert = 3*other.nvert_*sizeof(float); this->vert_ = (float*)mju_malloc(nvert); memcpy(this->vert_, other.vert_, nvert); + } else { + this->vert_ = NULL; } if (other.normal_) { size_t nnormal = 3*other.nnormal_*sizeof(float); this->normal_ = (float*)mju_malloc(nnormal); memcpy(this->normal_, other.normal_, nnormal); + } else { + this->normal_ = NULL; } if (other.center_) { size_t ncenter = 3*other.nface_*sizeof(double); this->center_ = (double*)mju_malloc(ncenter); memcpy(this->center_, other.center_, ncenter); + } else { + this->center_ = NULL; } if (other.texcoord_) { size_t ntexcoord = 2*other.ntexcoord_*sizeof(float); this->texcoord_ = (float*)mju_malloc(ntexcoord); memcpy(this->texcoord_, other.texcoord_, ntexcoord); + } else { + this->texcoord_ = NULL; } if (other.face_) { size_t nface = 3*other.nface_*sizeof(int); this->face_ = (int*)mju_malloc(nface); memcpy(this->face_, other.face_, nface); + } else { + this->face_ = NULL; } if (other.facenormal_) { size_t nfacenormal = 3*other.nface_*sizeof(int); this->facenormal_ = (int*)mju_malloc(nfacenormal); memcpy(this->facenormal_, other.facenormal_, nfacenormal); + } else { + this->facenormal_ = NULL; } if (other.facetexcoord_) { size_t nfacetexcoord = 3*other.nface_*sizeof(int); this->facetexcoord_ = (int*)mju_malloc(nfacetexcoord); memcpy(this->facetexcoord_, other.facetexcoord_, nfacetexcoord); + } else { + this->facetexcoord_ = NULL; } if (other.graph_) { size_t szgraph = szgraph_*sizeof(int); this->graph_ = (int*)mju_malloc(szgraph); memcpy(this->graph_, other.graph_, szgraph); + } else { + this->graph_ = NULL; + } + if (other.plugin.instance) { + mjCPlugin* new_plugin = new mjCPlugin(*reinterpret_cast(other.plugin.instance)); + plugin = new_plugin->spec; + model->plugins.push_back(new_plugin); } } PointToLocal(); @@ -2061,6 +2082,24 @@ mjCSkin::mjCSkin(mjCModel* _model) { +mjCSkin::mjCSkin(const mjCSkin& other) { + *this = other; +} + + + +mjCSkin& mjCSkin::operator=(const mjCSkin& other) { + if (this != &other) { + this->spec = other.spec; + *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); + } + PointToLocal(); + return *this; +} + + + void mjCSkin::PointToLocal() { spec.element = (mjElement)this; spec.name = (mjString)&name; diff --git a/src/user/user_model.cc b/src/user/user_model.cc index c5426ac0..89960178 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -138,6 +138,175 @@ mjCModel::mjCModel() { world->def = defaults[0]; bodies.push_back(world); + // create mjCBase lists from children lists + CreateObjectLists(); + + // point to model from spec + PointToLocal(); + + // this class allocated the plugins + plugin_owner = true; +} + + + +mjCModel::mjCModel(const mjCModel& other) { + *this = other; +} + + + +mjCModel& mjCModel::operator=(const mjCModel& other) { + if (this != &other) { + plugin_owner = false; + this->spec = other.spec; + *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); + std::map def_map; + for (int i = 0; i < other.defaults.size(); i++) { + defaults.push_back(new mjCDef(*other.defaults[i])); + def_map[other.defaults[i]] = i; + } + for (const mjCFlex* flex : other.flexes) { + flexes.push_back(new mjCFlex(*flex)); + flexes.back()->model = this; + flexes.back()->def = defaults[def_map[flex->def]]; + } + for (const mjCMesh* mesh : other.meshes) { + meshes.push_back(new mjCMesh(*mesh)); + meshes.back()->model = this; + meshes.back()->def = defaults[def_map[mesh->def]]; + } + for (const mjCSkin* skin : other.skins) { + skins.push_back(new mjCSkin(*skin)); + skins.back()->model = this; + skins.back()->def = defaults[def_map[skin->def]]; + } + for (const mjCHField* hfield : other.hfields) { + hfields.push_back(new mjCHField(*hfield)); + hfields.back()->model = this; + hfields.back()->def = defaults[def_map[hfield->def]]; + } + for (const mjCTexture* texture : other.textures) { + textures.push_back(new mjCTexture(*texture)); + textures.back()->model = this; + textures.back()->def = defaults[def_map[texture->def]]; + } + for (const mjCMaterial* material : other.materials) { + materials.push_back(new mjCMaterial(*material)); + materials.back()->model = this; + materials.back()->def = defaults[def_map[material->def]]; + } + for (const mjCPair* pair : other.pairs) { + pairs.push_back(new mjCPair(*pair)); + pairs.back()->model = this; + pairs.back()->def = defaults[def_map[pair->def]]; + } + for (const mjCBodyPair* exclude : other.excludes) { + excludes.push_back(new mjCBodyPair(*exclude)); + excludes.back()->model = this; + excludes.back()->def = defaults[def_map[exclude->def]]; + } + for (const mjCEquality* equality : other.equalities) { + equalities.push_back(new mjCEquality(*equality)); + equalities.back()->model = this; + equalities.back()->def = defaults[def_map[equality->def]]; + } + for (const mjCTendon* tendon : other.tendons) { + tendons.push_back(new mjCTendon(*tendon)); + tendons.back()->SetModel(this); + tendons.back()->def = defaults[def_map[tendon->def]]; + } + for (const mjCActuator* actuator : other.actuators) { + actuators.push_back(new mjCActuator(*actuator)); + actuators.back()->model = this; + actuators.back()->def = defaults[def_map[actuator->def]]; + } + for (const mjCSensor* sensor : other.sensors) { + sensors.push_back(new mjCSensor(*sensor)); + sensors.back()->model = this; + sensors.back()->def = defaults[def_map[sensor->def]]; + } + for (const mjCNumeric* numeric : other.numerics) { + numerics.push_back(new mjCNumeric(*numeric)); + numerics.back()->model = this; + numerics.back()->def = defaults[def_map[numeric->def]]; + } + for (const mjCText* text : other.texts) { + texts.push_back(new mjCText(*text)); + texts.back()->model = this; + texts.back()->def = defaults[def_map[text->def]]; + } + for (const mjCTuple* tuple : other.tuples) { + tuples.push_back(new mjCTuple(*tuple)); + tuples.back()->model = this; + tuples.back()->def = defaults[def_map[tuple->def]]; + } + for (const mjCKey* key : other.keys) { + keys.push_back(new mjCKey(*key)); + keys.back()->model = this; + keys.back()->def = defaults[def_map[key->def]]; + } + + // plugins are global + plugins = other.plugins; + active_plugins = other.active_plugins; + + // the world copy constructor takes care of copying the tree + mjCBody* world = new mjCBody(*other.bodies[0], this); + + // create global lists + bodies.push_back(world); + MakeLists(bodies[0]); + + // update defaults for the copied objects + for (int i = 1; i < other.bodies.size(); i++) { + bodies[i]->def = defaults[def_map[other.bodies[i]->def]]; + } + for (int i = 0; i < other.joints.size(); i++) { + joints[i]->def = defaults[def_map[other.joints[i]->def]]; + } + for (int i = 0; i < other.geoms.size(); i++) { + geoms[i]->def = defaults[def_map[other.geoms[i]->def]]; + } + for (int i = 0; i < other.sites.size(); i++) { + sites[i]->def = defaults[def_map[other.sites[i]->def]]; + } + for (int i = 0; i < other.cameras.size(); i++) { + cameras[i]->def = defaults[def_map[other.cameras[i]->def]]; + } + for (int i = 0; i < other.lights.size(); i++) { + lights[i]->def = defaults[def_map[other.lights[i]->def]]; + } + + // copy name maps + for (int i=0; i*) &tuples; object_lists[mjOBJ_KEY] = (std::vector*) &keys; object_lists[mjOBJ_PLUGIN] = (std::vector*) &plugins; - - - // point to model from spec - PointToLocal(); -} - - - -mjCModel::mjCModel(const mjCModel& other) { - *this = other; - PointToLocal(); } @@ -230,9 +388,12 @@ mjCModel::~mjCModel() { for (int i=0; ihfield_adr[i] = data_adr; // copy elevation data - memcpy(m->hfield_data + data_adr, phf->data, phf->nrow*phf->ncol*sizeof(float)); + memcpy(m->hfield_data + data_adr, phf->data.data(), phf->nrow*phf->ncol*sizeof(float)); // advance counter data_adr += phf->nrow*phf->ncol; @@ -2163,7 +2316,7 @@ void mjCModel::CopyObjects(mjModel* m) { m->tex_adr[i] = data_adr; // copy rgb data - memcpy(m->tex_rgb + data_adr, ptex->rgb, 3*ptex->width*ptex->height); + memcpy(m->tex_rgb + data_adr, ptex->rgb.data(), 3*ptex->width*ptex->height); // advance counter data_adr += 3*ptex->width*ptex->height; diff --git a/src/user/user_model.h b/src/user/user_model.h index 629ec578..01b9b962 100644 --- a/src/user/user_model.h +++ b/src/user/user_model.h @@ -33,133 +33,9 @@ typedef std::map > mjKeyMap; typedef std::array mjListKeyMap; -// mjCModel contains everything needed to generate the low-level model. -// It can be constructed manually by calling 'Add' functions and setting -// the public fields of the various objects. Alternatively it can constructed -// by loading an XML file via mjCXML. Once an mjCModel object is -// constructed, 'Compile' can be called to generate the corresponding mjModel object -// (which is the low-level model). The mjCModel object can then be deleted. -class mjCModel : private mjSpec { - friend class mjCBody; - friend class mjCCamera; - friend class mjCGeom; - friend class mjCFlex; - friend class mjCHField; - friend class mjCFrame; - friend class mjCJoint; - friend class mjCEquality; - friend class mjCMesh; - friend class mjCSkin; - friend class mjCSite; - friend class mjCTendon; - friend class mjCTexture; - friend class mjCActuator; - friend class mjCSensor; - friend class mjCDef; - friend class mjXReader; - friend class mjXWriter; - - public: - mjCModel(); - mjCModel(const mjCModel& other); - ~mjCModel(); - void CopyFromSpec(); // copy spec to private attributes - void PointToLocal(); - - mjSpec spec; - - mjModel* Compile(const mjVFS* vfs = nullptr); // construct mjModel - bool CopyBack(const mjModel*); // DECOMPILER: copy numeric back - void FuseStatic(); // fuse static bodies with parent - void FuseReindex(mjCBody* body); // reindex elements during fuse - - // API for adding model elements - mjCFlex* AddFlex(); - mjCMesh* AddMesh(mjCDef* def = nullptr); - mjCSkin* AddSkin(); - mjCHField* AddHField(); - mjCTexture* AddTexture(); - mjCMaterial* AddMaterial(mjCDef* def = nullptr); - mjCPair* AddPair(mjCDef* def = nullptr); // geom pair for inclusion - mjCBodyPair* AddExclude(); // body pair for exclusion - mjCEquality* AddEquality(mjCDef* def = nullptr); // equality constraint - mjCTendon* AddTendon(mjCDef* def = nullptr); - mjCActuator* AddActuator(mjCDef* def = nullptr); - mjCSensor* AddSensor(); - mjCNumeric* AddNumeric(); - mjCText* AddText(); - mjCTuple* AddTuple(); - mjCKey* AddKey(); - mjCPlugin* AddPlugin(); - - // delete elements marked as discard=true - template void Delete(std::vector& elements, - const std::vector& discard); - - // delete all elements - template void DeleteAll(std::vector& elements); - - // API for access to model elements (outside tree) - int NumObjects(mjtObj type); // number of objects in specified list - mjCBase* GetObject(mjtObj type, int id); // pointer to specified object - - // API for access to other variables - bool IsCompiled(); // is model already compiled - int GetFixed(); // number of fixed massless bodies - const mjCError& GetError(void); // get reference of error object - mjCBody* GetWorld(); // pointer to world body - mjCDef* FindDef(std::string name); // find default class name - mjCDef* AddDef(std::string name, int parentid); // add default class to array - mjCBase* FindObject(mjtObj type, std::string name); // find object given type and name - bool IsNullPose(const mjtNum* pos, const mjtNum* quat); // detect null pose - - // accessors - std::string get_meshdir(void) const { return meshdir_; } - std::string get_texturedir(void) const { return texturedir_; } - - // resolve plugin instance, create a new one if needed - void ResolvePlugin(mjCBase* obj, const std::string& plugin_name, - const std::string& plugin_instance_name, - mjCPlugin** plugin_instance); - - // settings for each defaults class - std::vector defaults; - - // list of active plugins - std::vector> active_plugins; - - private: - void TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs); - mjModel* _Compile(const mjVFS* vfs); - - // clear objects allocated by Compile - void Clear(void); - - // add object of any type - template T* AddObject(std::vector& list, std::string type); - - // add object of any type, with def parameter - template T* AddObjectDef(std::vector& list, std::string type, - mjCDef* def); - - // if asset name is missing, set to filename - template void SetDefaultNames(std::vector& assets); - - // delete material from object - template void DeleteMaterial(std::vector& list, - std::string_view name = ""); - - // compile phases - void MakeLists(mjCBody* body); // make lists of bodies, geoms, joints, sites - void IndexAssets(bool discard); // convert asset names into indices - void CheckEmptyNames(); // check empty names - void SetSizes(); // compute sizes - void AutoSpringDamper(mjModel*); // automatic stiffness and damping computation - void LengthRange(mjModel*, mjData*); // compute actuator lengthrange - void CopyNames(mjModel*); // copy names, compute name addresses - void CopyPaths(mjModel*); // copy paths, compute path addresses - void CopyObjects(mjModel*); // copy objects outside kinematic tree - void CopyTree(mjModel*); // copy objects inside kinematic tree +class mjCModel_ { + protected: + bool compiled; // already compiled flag // sizes set from object list lengths int nbody; // number of bodies @@ -224,6 +100,158 @@ class mjCModel : private mjSpec { int nD; // number of non-zeros in sparse dof-dof matrix int nB; // number of non-zeros in sparse body-dof matrix + // statistics, as computed by mj_setConst + double meaninertia_auto; // mean diagonal inertia, as computed by mj_setConst + double meanmass_auto; // mean body mass, as computed by mj_setConst + double meansize_auto; // mean body size, as computed by mj_setConst + double extent_auto; // spatial extent, as computed by mj_setConst + double center_auto[3]; // center of model, as computed by mj_setConst + + // save qpos0, to recognize changed key_qpos in write + std::vector qpos0; + + // variable-size attributes + std::string comment_; // comment at top of XML + std::string modelfiledir_; // path to model file + std::string modelname_; + std::string meshdir_; + std::string texturedir_; + std::string spec_comment_; + std::string spec_modelfiledir_; + std::string spec_modelname_; + std::string spec_meshdir_; + std::string spec_texturedir_; +}; + +// mjCModel contains everything needed to generate the low-level model. +// It can be constructed manually by calling 'Add' functions and setting +// the public fields of the various objects. Alternatively it can constructed +// by loading an XML file via mjCXML. Once an mjCModel object is +// constructed, 'Compile' can be called to generate the corresponding mjModel object +// (which is the low-level model). The mjCModel object can then be deleted. +class mjCModel : public mjCModel_, private mjSpec { + friend class mjCBase; + friend class mjCBody; + friend class mjCCamera; + friend class mjCGeom; + friend class mjCFlex; + friend class mjCHField; + friend class mjCFrame; + friend class mjCJoint; + friend class mjCEquality; + friend class mjCMesh; + friend class mjCSkin; + friend class mjCSite; + friend class mjCTendon; + friend class mjCTexture; + friend class mjCActuator; + friend class mjCSensor; + friend class mjCDef; + friend class mjXReader; + friend class mjXWriter; + + public: + mjCModel(); + mjCModel(const mjCModel& other); + mjCModel& operator=(const mjCModel& other); + ~mjCModel(); + void CopyFromSpec(); // copy spec to private attributes + void PointToLocal(); + + mjSpec spec; + + mjModel* Compile(const mjVFS* vfs = nullptr); // construct mjModel + bool CopyBack(const mjModel*); // DECOMPILER: copy numeric back + void FuseStatic(); // fuse static bodies with parent + void FuseReindex(mjCBody* body); // reindex elements during fuse + + // API for adding model elements + mjCFlex* AddFlex(); + mjCMesh* AddMesh(mjCDef* def = nullptr); + mjCSkin* AddSkin(); + mjCHField* AddHField(); + mjCTexture* AddTexture(); + mjCMaterial* AddMaterial(mjCDef* def = nullptr); + mjCPair* AddPair(mjCDef* def = nullptr); // geom pair for inclusion + mjCBodyPair* AddExclude(); // body pair for exclusion + mjCEquality* AddEquality(mjCDef* def = nullptr); // equality constraint + mjCTendon* AddTendon(mjCDef* def = nullptr); + mjCActuator* AddActuator(mjCDef* def = nullptr); + mjCSensor* AddSensor(); + mjCNumeric* AddNumeric(); + mjCText* AddText(); + mjCTuple* AddTuple(); + mjCKey* AddKey(); + mjCPlugin* AddPlugin(); + + // delete elements marked as discard=true + template void Delete(std::vector& elements, + const std::vector& discard); + + // delete all elements + template void DeleteAll(std::vector& elements); + + // API for access to model elements (outside tree) + int NumObjects(mjtObj type); // number of objects in specified list + mjCBase* GetObject(mjtObj type, int id); // pointer to specified object + + // API for access to other variables + bool IsCompiled(); // is model already compiled + const mjCError& GetError(void); // get reference of error object + mjCBody* GetWorld(); // pointer to world body + mjCDef* FindDef(std::string name); // find default class name + mjCDef* AddDef(std::string name, int parentid); // add default class to array + mjCBase* FindObject(mjtObj type, std::string name); // find object given type and name + bool IsNullPose(const mjtNum* pos, const mjtNum* quat); // detect null pose + + // accessors + std::string get_meshdir(void) const { return meshdir_; } + std::string get_texturedir(void) const { return texturedir_; } + + // resolve plugin instance, create a new one if needed + void ResolvePlugin(mjCBase* obj, const std::string& plugin_name, + const std::string& plugin_instance_name, + mjCPlugin** plugin_instance); + + // settings for each defaults class + std::vector defaults; + + // list of active plugins + std::vector> active_plugins; + + private: + void TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs); + mjModel* _Compile(const mjVFS* vfs); + + // clear objects allocated by Compile + void Clear(void); + + // add object of any type + template T* AddObject(std::vector& list, std::string type); + + // add object of any type, with def parameter + template T* AddObjectDef(std::vector& list, std::string type, + mjCDef* def); + + // if asset name is missing, set to filename + template void SetDefaultNames(std::vector& assets); + + // delete material from object + template void DeleteMaterial(std::vector& list, + std::string_view name = ""); + + // compile phases + void MakeLists(mjCBody* body); // make lists of bodies, geoms, joints, sites + void IndexAssets(bool discard); // convert asset names into indices + void CheckEmptyNames(); // check empty names + void SetSizes(); // compute sizes + void AutoSpringDamper(mjModel*); // automatic stiffness and damping computation + void LengthRange(mjModel*, mjData*); // compute actuator lengthrange + void CopyNames(mjModel*); // copy names, compute name addresses + void CopyPaths(mjModel*); // copy paths, compute path addresses + void CopyObjects(mjModel*); // copy objects outside kinematic tree + void CopyTree(mjModel*); // copy objects inside kinematic tree + // objects created here std::vector flexes; // list of flexes std::vector meshes; // list of meshes @@ -255,32 +283,11 @@ class mjCModel : private mjSpec { // array of pointers to each object list (enumerated by type) std::array*, mjNOBJECT> object_lists; - // statistics, as computed by mj_setConst - double meaninertia_auto; // mean diagonal inertia, as computed by mj_setConst - double meanmass_auto; // mean body mass, as computed by mj_setConst - double meansize_auto; // mean body size, as computed by mj_setConst - double extent_auto; // spatial extent, as computed by mj_setConst - double center_auto[3]; // center of model, as computed by mj_setConst - + // create mjCBase lists from children lists + void CreateObjectLists(); mjListKeyMap ids; // map from object names to ids - bool compiled; // already compiled flag (cannot be compiled again) mjCError errInfo; // last error info - int fixCount; // how many bodies have been fixed - - // save qpos0, to recognize changed key_qpos in write - std::vector qpos0; - - // variable-size attributes - std::string comment_; // comment at top of XML - std::string modelfiledir_; // path to model file - std::string modelname_; - std::string meshdir_; - std::string texturedir_; - std::string spec_comment_; - std::string spec_modelfiledir_; - std::string spec_modelname_; - std::string spec_meshdir_; - std::string spec_texturedir_; + bool plugin_owner; // this class allocated the plugins }; #endif // MUJOCO_SRC_USER_USER_MODEL_H_ diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index 997bcde4..adc45bc5 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -570,12 +570,6 @@ mjCBase::mjCBase(const mjCBase& other) { mjCBase& mjCBase::operator=(const mjCBase& other) { if (this != &other) { *static_cast(this) = static_cast(other); - if (other.def) { - def = new mjCDef(*other.def); - } - if (other.frame) { - frame = new mjCFrame(*other.frame); - } } return *this; } @@ -663,7 +657,8 @@ mjCBody::mjCBody(mjCModel* _model) { -mjCBody::mjCBody(const mjCBody& other) { +mjCBody::mjCBody(const mjCBody& other, mjCModel* _model) { + model = _model; *this = other; } @@ -671,43 +666,63 @@ mjCBody::mjCBody(const mjCBody& other) { mjCBody& mjCBody::operator=(const mjCBody& other) { if (this != &other) { - this->spec = other.spec; + spec = other.spec; *static_cast(this) = static_cast(other); *static_cast(this) = static_cast(other); - this->bodies.clear(); - this->frames.clear(); - this->geoms.clear(); - this->joints.clear(); - this->sites.clear(); - this->cameras.clear(); - this->lights.clear(); + std::map fmap; + mjCFrame *np = nullptr; + bodies.clear(); + frames.clear(); + geoms.clear(); + joints.clear(); + sites.clear(); + cameras.clear(); + lights.clear(); + + // create frames and map them to the old ones + for (int i=0; imodel = model; + fmap[other.frames[i]] = i; + } // copy all children for (int i=0; ibodies.push_back(new mjCBody(*other.bodies[i])); // triggers recursive call + bodies.push_back(new mjCBody(*other.bodies[i], model)); // triggers recursive call + bodies.back()->frame = other.bodies[i]->frame ? frames[fmap[other.bodies[i]->frame]] : np; } for (int i=0; iframes.push_back(new mjCFrame(*other.frames[i])); + frames[i]->frame = other.frames[i]->frame ? frames[fmap[other.frames[i]->frame]] : np; } for (int i=0; igeoms.push_back(new mjCGeom(*other.geoms[i])); - this->geoms.back()->body = this; + geoms.push_back(new mjCGeom(*other.geoms[i])); + geoms.back()->body = this; + geoms.back()->model = model; + geoms.back()->frame = other.geoms[i]->frame ? frames[fmap[other.geoms[i]->frame]] : np; } for (int i=0; ijoints.push_back(new mjCJoint(*other.joints[i])); - this->joints.back()->body = this; + joints.push_back(new mjCJoint(*other.joints[i])); + joints.back()->body = this; + joints.back()->model = model; + joints.back()->frame = other.joints[i]->frame ? frames[fmap[other.joints[i]->frame]] : np; } for (int i=0; isites.push_back(new mjCSite(*other.sites[i])); - this->sites.back()->body = this; + sites.push_back(new mjCSite(*other.sites[i])); + sites.back()->body = this; + sites.back()->model = model; + sites.back()->frame = other.sites[i]->frame ? frames[fmap[other.sites[i]->frame]] : np; } for (int i=0; icameras.push_back(new mjCCamera(*other.cameras[i])); - this->cameras.back()->body = this; + cameras.push_back(new mjCCamera(*other.cameras[i])); + cameras.back()->body = this; + cameras.back()->model = model; + cameras.back()->frame = other.cameras[i]->frame ? frames[fmap[other.cameras[i]->frame]] : np; } for (int i=0; ilights.push_back(new mjCLight(*other.lights[i])); - this->lights.back()->body = this; + lights.push_back(new mjCLight(*other.lights[i])); + lights.back()->body = this; + lights.back()->model = model; + lights.back()->frame = other.lights[i]->frame ? frames[fmap[other.lights[i]->frame]] : np; } } PointToLocal(); @@ -2618,7 +2633,7 @@ mjCHField::mjCHField(mjCModel* _model) { model = _model; // clear variables - data = 0; + data.clear(); spec_file_.clear(); spec_userdata_.clear(); @@ -2631,6 +2646,24 @@ mjCHField::mjCHField(mjCModel* _model) { +mjCHField::mjCHField(const mjCHField& other) { + *this = other; +} + + + +mjCHField& mjCHField::operator=(const mjCHField& other) { + if (this != &other) { + this->spec = other.spec; + *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); + } + PointToLocal(); + return *this; +} + + + void mjCHField::PointToLocal() { spec.element = (mjElement)this; spec.name = (mjString)&name; @@ -2652,10 +2685,7 @@ void mjCHField::CopyFromSpec() { userdata = (mjFloatVec)&userdata_; // clear precompiled asset. TODO: use asset cache - if (data) { - mju_free(data); - data = 0; - } + data.clear(); if (!file_.empty()) { nrow = 0; ncol = 0; @@ -2666,9 +2696,7 @@ void mjCHField::CopyFromSpec() { // destructor mjCHField::~mjCHField() { - if (data) { - mju_free(data); - } + data.clear(); userdata_.clear(); spec_userdata_.clear(); } @@ -2708,13 +2736,13 @@ void mjCHField::LoadCustom(mjResource* resource) { } // allocate - data = (float*) mju_malloc(nrow*ncol*sizeof(float)); - if (!data) { + data.assign(nrow*ncol, 0); + if (data.empty()) { throw mjCError(this, "could not allocate buffers in hfield"); } // copy data - memcpy(data, (void*)(pint+2), nrow*ncol*sizeof(float)); + memcpy(data.data(), (void*)(pint+2), nrow*ncol*sizeof(float)); } @@ -2747,8 +2775,8 @@ void mjCHField::LoadPNG(mjResource* resource) { } // allocate - data = (float*) mju_malloc(w*h*sizeof(float)); - if (!data) { + data.assign(w*h, 0); + if (data.empty()) { throw mjCError(this, "could not allocate buffers in hfield"); } @@ -2770,11 +2798,11 @@ void mjCHField::Compile(const mjVFS* vfs) { // copy userdata into data if (!userdata_.empty()) { - data = (float*) mju_malloc(nrow*ncol*sizeof(float)); - if (!data) { + data.assign(nrow*ncol, 0); + if (data.empty()) { throw mjCError(this, "could not allocate buffers in hfield"); } - memcpy(data, userdata_.data(), nrow*ncol*sizeof(float)); + memcpy(data.data(), userdata_.data(), nrow*ncol*sizeof(float)); } // check size parameters @@ -2791,7 +2819,7 @@ void mjCHField::Compile(const mjVFS* vfs) { // load from file if specified if (!file_.empty()) { // make sure hfield was not already specified manually - if (nrow || ncol || data) { + if (nrow || ncol || !data.empty()) { throw mjCError(this, "hfield '%s' (id = %d) specified from file and manually", name.c_str(), id); } @@ -2824,7 +2852,7 @@ void mjCHField::Compile(const mjVFS* vfs) { } // make sure hfield was specified (from file or manually) - if (nrow<1 || ncol<1 || data==0) { + if (nrow<1 || ncol<1 || data.empty()) { throw mjCError(this, "hfield '%s' (id = %d) not specified", name.c_str(), id); } @@ -2864,7 +2892,7 @@ mjCTexture::mjCTexture(mjCModel* _model) { spec_cubefiles_.assign(6, ""); // clear internal variables - rgb = 0; + rgb.clear(); // point to local PointToLocal(); @@ -2875,6 +2903,23 @@ mjCTexture::mjCTexture(mjCModel* _model) { +mjCTexture::mjCTexture(const mjCTexture& other) { + *this = other; +} + + + +mjCTexture& mjCTexture::operator=(const mjCTexture& other) { + if (this != &other) { + this->spec = other.spec; + *static_cast(this) = static_cast(other); + } + PointToLocal(); + return *this; +} + + + void mjCTexture::PointToLocal() { spec.element = (mjElement)this; spec.name = (mjString)&name; @@ -2897,20 +2942,14 @@ void mjCTexture::CopyFromSpec() { cubefiles = (mjStringVec)&cubefiles_; // clear precompiled asset. TODO: use asset cache - if (rgb) { - mju_free(rgb); - rgb = 0; - } + rgb.clear(); } // free data storage allocated by lodepng mjCTexture::~mjCTexture() { - if (rgb) { - mju_free(rgb); - rgb = 0; - } + rgb.clear(); } @@ -2997,21 +3036,21 @@ void mjCTexture::Builtin2D(void) { double pos = 2*sqrt(x*x+y*y) - 1; // interpolate through sigmoid - interp(rgb + 3*(r*width+c), rgb2, rgb1, pos); + interp(rgb.data() + 3*(r*width+c), rgb2, rgb1, pos); } } } // checker else if (builtin==mjBUILTIN_CHECKER) { - checker(rgb, RGB1, RGB2, width, height); + checker(rgb.data(), RGB1, RGB2, width, height); } // flat else if (builtin==mjBUILTIN_FLAT) { for (int r=0; r0) { - randomdot(rgb, markrgb, width, height, random); + randomdot(rgb.data(), markrgb, width, height, random); } } @@ -3051,65 +3090,67 @@ void mjCTexture::Builtin2D(void) { // make builtin: Cube void mjCTexture::BuiltinCube(void) { unsigned char RGB1[3], RGB2[3], RGBm[3], RGBi[3]; + int w = width; + int ww = width*width; // convert fixed colors - for (int j=0; j<3; j++) { - RGB1[j] = (mjtByte)(255*rgb1[j]); - RGB2[j] = (mjtByte)(255*rgb2[j]); - RGBm[j] = (mjtByte)(255*markrgb[j]); + for (int j = 0; j < 3; j++) { + RGB1[j] = (mjtByte)(255 * rgb1[j]); + RGB2[j] = (mjtByte)(255 * rgb2[j]); + RGBm[j] = (mjtByte)(255 * markrgb[j]); } //------------------ faces // gradient - if (builtin==mjBUILTIN_GRADIENT) { - for (int r=0; r0) { - randomdot(rgb, markrgb, width, height, random); + else if (mark == mjMARK_RANDOM && random > 0) { + randomdot(rgb.data(), markrgb, w, height, random); } } - - // load PNG file void mjCTexture::LoadPNG(mjResource* resource, std::vector& image, @@ -3307,12 +3346,12 @@ void mjCTexture::Load2D(string filename, const mjVFS* vfs) { height = h; // allocate and copy data - rgb = (mjtByte*) mju_malloc(3*width*height); - if (!rgb) { + rgb.assign(3*width*height, 0); + if (rgb.empty()) { throw mjCError(this, "Could not allocate memory for texture '%s' (id %d)", (const char*)file_.c_str(), id); } - memcpy(rgb, image.data(), 3*width*height); + memcpy(rgb.data(), image.data(), 3*width*height); image.clear(); } @@ -3348,8 +3387,8 @@ void mjCTexture::LoadCubeSingle(string filename, const mjVFS* vfs) { } // allocate data - rgb = (mjtByte*) mju_malloc(3*width*height); - if (!rgb) { + rgb.assign(3*width*height, 0); + if (rgb.empty()) { throw mjCError(this, "Could not allocate memory for texture '%s' (id %d)", (const char*)file_.c_str(), id); @@ -3357,7 +3396,7 @@ void mjCTexture::LoadCubeSingle(string filename, const mjVFS* vfs) { // copy: repeated if (gridsize[0]==1 && gridsize[1]==1) { - memcpy(rgb, image.data(), 3*width*width); + memcpy(rgb.data(), image.data(), 3*width*width); } // copy: grid @@ -3391,7 +3430,7 @@ void mjCTexture::LoadCubeSingle(string filename, const mjVFS* vfs) { int rstart = width*(k/gridsize[1]); int cstart = width*(k%gridsize[1]); for (int j=0; jspec = other.spec; + *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); + } + PointToLocal(); + return *this; +} + + + void mjCBodyPair::PointToLocal() { spec.element = (mjElement)this; spec.name = (mjString)&name; @@ -4114,8 +4171,12 @@ mjCTendon::mjCTendon(const mjCTendon& other) { mjCTendon& mjCTendon::operator=(const mjCTendon& other) { if (this != &other) { this->spec = other.spec; + *static_cast(this) = static_cast(other); *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + for (int i=0; itendon = this; + } } PointToLocal(); return *this; @@ -4166,6 +4227,15 @@ mjCTendon::~mjCTendon() { +void mjCTendon::SetModel(mjCModel* _model) { + model = _model; + for (int i=0; imodel = _model; + } +} + + + // add site as wrap object void mjCTendon::WrapSite(string name, std::string_view info) { // create wrap object @@ -4395,6 +4465,25 @@ mjCWrap::mjCWrap(mjCModel* _model, mjCTendon* _tendon) { +mjCWrap::mjCWrap(const mjCWrap& other) { + *this = other; +} + + + +mjCWrap& mjCWrap::operator=(const mjCWrap& other) { + if (this != &other) { + this->spec = other.spec; + *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); + obj = nullptr; + } + PointToLocal(); + return *this; +} + + + void mjCWrap::PointToLocal() { spec.element = (mjElement)this; spec.info = (mjString)&info; @@ -4822,12 +4911,30 @@ mjCSensor::mjCSensor(mjCModel* _model) { CopyFromSpec(); // point to local - MakePointerLocal(); + PointToLocal(); } -void mjCSensor::MakePointerLocal() { +mjCSensor::mjCSensor(const mjCSensor& other) { + *this = other; +} + + + +mjCSensor& mjCSensor::operator=(const mjCSensor& other) { + if (this != &other) { + this->spec = other.spec; + *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); + } + PointToLocal(); + return *this; +} + + + +void mjCSensor::PointToLocal() { spec.element = (mjElement)this; spec.name = (mjString)&name; spec.classname = (mjString)&classname; @@ -5271,6 +5378,24 @@ mjCNumeric::mjCNumeric(mjCModel* _model) { +mjCNumeric::mjCNumeric(const mjCNumeric& other) { + *this = other; +} + + + +mjCNumeric& mjCNumeric::operator=(const mjCNumeric& other) { + if (this != &other) { + this->spec = other.spec; + *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); + } + PointToLocal(); + return *this; +} + + + void mjCNumeric::PointToLocal() { spec.element = (mjElement)this; spec.name = (mjString)&name; @@ -5341,6 +5466,24 @@ mjCText::mjCText(mjCModel* _model) { +mjCText::mjCText(const mjCText& other) { + *this = other; +} + + + +mjCText& mjCText::operator=(const mjCText& other) { + if (this != &other) { + this->spec = other.spec; + *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); + } + PointToLocal(); + return *this; +} + + + void mjCText::PointToLocal() { spec.element = (mjElement)this; spec.name = (mjString)&name; @@ -5402,6 +5545,24 @@ mjCTuple::mjCTuple(mjCModel* _model) { +mjCTuple::mjCTuple(const mjCTuple& other) { + *this = other; +} + + + +mjCTuple& mjCTuple::operator=(const mjCTuple& other) { + if (this != &other) { + this->spec = other.spec; + *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); + } + PointToLocal(); + return *this; +} + + + void mjCTuple::PointToLocal() { spec.element = (mjElement)this; spec.name = (mjString)&name; @@ -5502,6 +5663,24 @@ mjCKey::mjCKey(mjCModel* _model) { +mjCKey::mjCKey(const mjCKey& other) { + *this = other; +} + + + +mjCKey& mjCKey::operator=(const mjCKey& other) { + if (this != &other) { + this->spec = other.spec; + *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); + } + PointToLocal(); + return *this; +} + + + void mjCKey::PointToLocal() { spec.element = (mjElement)this; spec.name = (mjString)&name; @@ -5653,6 +5832,23 @@ mjCPlugin::mjCPlugin(mjCModel* _model) { +mjCPlugin::mjCPlugin(const mjCPlugin& other) { + *this = other; +} + + + +mjCPlugin& mjCPlugin::operator=(const mjCPlugin& other) { + if (this != &other) { + this->spec = other.spec; + *static_cast(this) = static_cast(other); + parent = this; + } + return *this; +} + + + // compiler void mjCPlugin::Compile(void) { const mjpPlugin* plugin = mjp_getPluginAtSlot(spec.plugin_slot); diff --git a/src/user/user_objects.h b/src/user/user_objects.h index 01333478..f553df97 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -177,7 +177,6 @@ class mjCBase_ { std::string classname; // defaults class name int id; // object id std::string info; // error message info set by the user - mjCModel* model; // pointer to model that created object }; class mjCBase : public mjCBase_ { @@ -202,6 +201,7 @@ class mjCBase : public mjCBase_ { mjCDef* def; // defaults class used to init this object mjCFrame* frame; // pointer to frame transformation + mjCModel* model; // pointer to model that created object protected: mjCBase(); // constructor @@ -296,10 +296,10 @@ class mjCBody : public mjCBody_, private mjmBody { const std::vector& get_userdata() { return userdata_; } private: - mjCBody(mjCModel*); // constructor - mjCBody(const mjCBody& other); // copy constructor - mjCBody& operator=(const mjCBody& other); // copy assignment - ~mjCBody(); // destructor + mjCBody(mjCModel*); // constructor + mjCBody(const mjCBody& other, mjCModel* _model); // copy constructor + mjCBody& operator=(const mjCBody& other); // copy assignment + ~mjCBody(); // destructor void Compile(void); // compiler void GeomFrame(void); // get inertial info from geoms @@ -755,6 +755,7 @@ class mjCMesh_ : public mjCBase { }; class mjCMesh: public mjCMesh_, private mjmMesh { + friend class mjCModel; friend class mjCFlexcomp; friend class mjXWriter; public: @@ -932,6 +933,8 @@ class mjCSkin: public mjCSkin_, private mjmSkin { class mjCHField_ : public mjCBase { protected: + std::vector data; // elevation data, row-major format + std::string file_; std::string content_type_; std::vector userdata_; @@ -964,7 +967,6 @@ class mjCHField : public mjCHField_, private mjmHField { mjCHField& operator=(const mjCHField& other); // copy assignment ~mjCHField(); // destructor - float* data; // elevation data, row-major format void Compile(const mjVFS* vfs); // compiler void LoadCustom(mjResource* resource); // load from custom format @@ -978,6 +980,8 @@ class mjCHField : public mjCHField_, private mjmHField { class mjCTexture_ : public mjCBase { protected: + std::vector rgb; // rgb data + std::string file_; std::string content_type_; std::vector cubefiles_; @@ -1029,8 +1033,6 @@ class mjCTexture : public mjCTexture_, private mjmTexture { void LoadCustom(mjResource* resource, std::vector& image, unsigned int& w, unsigned int& h); - - mjtByte* rgb; // rgb data }; @@ -1247,6 +1249,7 @@ class mjCTendon : public mjCTendon_, private mjmTendon { void CopyFromSpec(); void PointToLocal(); + void SetModel(mjCModel* _model); bool is_limited() const; @@ -1315,10 +1318,10 @@ class mjCPlugin : public mjCPlugin_ { public: mjmPlugin spec; mjCBase* parent; // parent object (only used when generating error message) + mjCPlugin(const mjCPlugin& other); // copy constructor private: mjCPlugin(mjCModel*); // constructor - mjCPlugin(const mjCPlugin& other); // copy constructor mjCPlugin& operator=(const mjCPlugin& other); // copy assignment void Compile(void); // compiler @@ -1385,6 +1388,7 @@ class mjCActuator : public mjCActuator_, private mjmActuator { class mjCSensor_ : public mjCBase { protected: int refid; // id of reference frame + mjCBase* obj; // sensorized object // variable-size data std::string plugin_name; @@ -1420,9 +1424,7 @@ class mjCSensor : public mjCSensor_, private mjmSensor { void Compile(void); // compiler void CopyFromSpec(); - void MakePointerLocal(); - - mjCBase* obj; // sensorized object + void PointToLocal(); }; diff --git a/test/user/user_api_test.cc b/test/user/user_api_test.cc index 926e8dc3..de1f9186 100644 --- a/test/user/user_api_test.cc +++ b/test/user/user_api_test.cc @@ -65,6 +65,9 @@ TEST_F(MujocoTest, ReadWriteData) { // ------------------- test recompilation multiple files ---------------------- TEST_F(PluginTest, RecompileCompare) { + mjtNum tol = 0; + std::string field = ""; + // full precision float printing FullFloatPrecision increase_precision; @@ -85,33 +88,55 @@ TEST_F(PluginTest, RecompileCompare) { continue; } - // load model - std::array error; - mjSpec* spec = - mjParseXML(xml.c_str(), nullptr, error.data(), error.size()); + // load spec + std::array err; + mjSpec* s = mjParseXML(xml.c_str(), nullptr, err.data(), err.size()); - // compile twice - mjModel* m_old = mjm_compile(spec, nullptr); - mjModel* m_new = mjm_compile(spec, nullptr); + // copy spec + mjSpec* s_copy = mjm_copySpec(s); + + // compile twice and compare + mjModel* m_old = mjm_compile(s, nullptr); + mjModel* m_new = mjm_compile(s, nullptr); + mjModel* m_copy = mjm_compile(s_copy, nullptr); ASSERT_THAT(m_old, NotNull()) - << "Failed to compile " << xml << ": " << error.data(); + << "Failed to compile " << xml << ": " << err.data(); ASSERT_THAT(m_new, NotNull()) - << "Failed to recompile " << xml << ": " << error.data(); + << "Failed to recompile " << xml << ": " << err.data(); + ASSERT_THAT(m_copy, NotNull()) + << "Failed to compile " << xml << ": " << err.data(); - // compare and delete - std::string field = ""; - mjtNum result = CompareModel(m_old, m_new, field); - mjtNum tol = 0; - EXPECT_LE(result, tol) - << "Loaded and saved models are different!\n" + EXPECT_LE(CompareModel(m_old, m_new, field), tol) + << "Compiled and recompiled models are different!\n" + << "Affected file " << p.path().string() << '\n' + << "Different field: " << field << '\n'; + + EXPECT_LE(CompareModel(m_old, m_copy, field), tol) + << "Original and copied models are different!\n" + << "Affected file " << p.path().string() << '\n' + << "Different field: " << field << '\n'; + + // copy to a new spec, compile and compare + mjSpec* s_copy2 = mjm_copySpec(s); + mjModel* m_copy2 = mjm_compile(s_copy2, nullptr); + + ASSERT_THAT(m_copy2, NotNull()) + << "Failed to compile " << xml << ": " << err.data(); + + EXPECT_LE(CompareModel(m_old, m_copy2, field), tol) + << "Original and re-copied models are different!\n" << "Affected file " << p.path().string() << '\n' << "Different field: " << field << '\n'; // delete models - mjm_deleteSpec(spec); + mjm_deleteSpec(s); + mjm_deleteSpec(s_copy); + mjm_deleteSpec(s_copy2); mj_deleteModel(m_old); mj_deleteModel(m_new); + mj_deleteModel(m_copy); + mj_deleteModel(m_copy2); } } } From c16a23d6c55e91905c3f11f50bf974507678c9d8 Mon Sep 17 00:00:00 2001 From: Kevin Zakka Date: Mon, 18 Mar 2024 13:21:44 -0700 Subject: [PATCH 19/51] Fix typo in least squares notebook. PiperOrigin-RevId: 616927630 Change-Id: I06f361a6ec55f37123bd9eced29111e1920b9dc7 --- python/least_squares.ipynb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/least_squares.ipynb b/python/least_squares.ipynb index 256ecbde..e382cdc7 100644 --- a/python/least_squares.ipynb +++ b/python/least_squares.ipynb @@ -234,10 +234,10 @@ "$$\n", "\\begin{aligned}\n", "x^* &= \\arg \\min_x f(x)\\\\\n", - "\\textrm{s.t.} &\\quad l \\succcurlyeq x \\succcurlyeq u\n", + "\\textrm{s.t.} &\\quad l \\preccurlyeq x \\preccurlyeq u\n", "\\end{aligned}\n", "$$\n", - "Where $l$ and $u$ are respectively lower and upper bound vectors and the inequalities $l \\succcurlyeq x \\succcurlyeq u$ are read elementwise. Solving for the minimizing $\\delta x$ is now a bit more involved than solving a linear system, and the optimization method is now referred to as [Sequential Quadratic Programming](https://en.wikipedia.org/wiki/Sequential_quadratic_programming) (SQP). Fortunately MuJoCo has an efficient box-constrained QP solver: the [mju_boxQP](https://mujoco.readthedocs.io/en/latest/APIreference/APIfunctions.html#mju-boxqp) function." + "Where $l$ and $u$ are respectively lower and upper bound vectors and the inequalities $l \\preccurlyeq x \\preccurlyeq u$ are read elementwise. Solving for the minimizing $\\delta x$ is now a bit more involved than solving a linear system, and the optimization method is now referred to as [Sequential Quadratic Programming](https://en.wikipedia.org/wiki/Sequential_quadratic_programming) (SQP). Fortunately MuJoCo has an efficient box-constrained QP solver: the [mju_boxQP](https://mujoco.readthedocs.io/en/latest/APIreference/APIfunctions.html#mju-boxqp) function." ] }, { From 91192393a0293d97bbb4bdd0fe7a16d8faf43bc0 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Mon, 18 Mar 2024 18:25:13 -0700 Subject: [PATCH 20/51] Add material and nonzero elevation data to hfield in testdata/model.xml PiperOrigin-RevId: 617011327 Change-Id: I46f4fdbd67027003a710a365d0ad29f9158ff85f --- test/testdata/model.xml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/testdata/model.xml b/test/testdata/model.xml index 5256859c..55b5c447 100644 --- a/test/testdata/model.xml +++ b/test/testdata/model.xml @@ -17,8 +17,13 @@ 1.618 0 -1 -1.618 0 1 -1.618 0 -1"/> - + + + @@ -41,7 +46,7 @@ - + From cc85a38f3c7c10aff6f5cb775bca102af7ae9e4f Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Tue, 19 Mar 2024 09:59:48 -0700 Subject: [PATCH 21/51] Add mjm_attachBody to the C API. PiperOrigin-RevId: 617207000 Change-Id: I1fe59ba0d79938a4a383b115997c31dd6c71b8e5 --- src/user/user_api.cc | 61 ++++++++++++++++++++----- src/user/user_api.h | 7 +++ src/user/user_model.cc | 68 ++++++++++++++++++++++++---- src/user/user_model.h | 3 ++ src/user/user_objects.cc | 45 +++++++++++++++++++ src/user/user_objects.h | 23 ++++++++-- src/xml/xml.cc | 33 +++++++++++++- src/xml/xml.h | 5 +++ test/user/user_api_test.cc | 91 ++++++++++++++++++++++++++++++++++++++ 9 files changed, 310 insertions(+), 26 deletions(-) diff --git a/src/user/user_api.cc b/src/user/user_api.cc index f14e75e3..10ebc5d1 100644 --- a/src/user/user_api.cc +++ b/src/user/user_api.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -28,6 +29,25 @@ #include "user/user_cache.h" #include "xml/xml_util.h" + +// prepend prefix +template +static T& operator+(std::string_view prefix, T& base) { + base.prefix = std::string(prefix); + return base; +} + + + +// append suffix +template +static T& operator+(T& base, std::string_view suffix) { + base.suffix = std::string(suffix); + return base; +} + + + // create model mjSpec* mjm_createSpec() { mjCModel* modelC = new mjCModel; @@ -60,6 +80,17 @@ mjModel* mjm_compile(mjSpec* s, const mjVFS* vfs) { +// attach body to a frame of the parent +int mjm_attachBody(mjmFrame* parent, const mjmBody* child, + const char* prefix, const char* suffix) { + mjCFrame* frame_parent = reinterpret_cast(parent->element); + mjCBody* child_body = reinterpret_cast(child->element); + *frame_parent += std::string(prefix) + *child_body + std::string(suffix); + return 0; +} + + + // get error message from model const char* mjm_getError(mjSpec* s) { mjCModel* modelC = reinterpret_cast(s->element); @@ -169,6 +200,7 @@ mjmFrame* mjm_addFrame(mjmBody* bodyspec, mjmFrame* parentframe) { } mjCBody* body = reinterpret_cast(bodyspec->element); mjCFrame* frameC = body->AddFrame(parentframeC); + frameC->SetParent(body); return &frameC->spec; } @@ -416,11 +448,13 @@ mjmDefault* mjm_getSpecDefault(mjSpec* s) { // find body in model by name mjmBody* mjm_findBody(mjSpec* s, const char* name) { mjCModel* model = reinterpret_cast(s->element); - mjCBase* body = model->FindObject(mjOBJ_BODY, std::string(name)); - if (!body) { - return 0; + mjCBase* body = 0; + if (model->IsCompiled()) { + body = model->FindObject(mjOBJ_BODY, std::string(name)); // fast lookup + } else { + body = model->FindBody(model->GetWorld(), std::string(name)); // recursive search } - return &(static_cast(body)->spec); + return body ? &(static_cast(body)->spec) : nullptr; } @@ -429,10 +463,7 @@ mjmBody* mjm_findBody(mjSpec* s, const char* name) { mjmBody* mjm_findChild(mjmBody* bodyspec, const char* name) { mjCBody* body = reinterpret_cast(bodyspec->element); mjCBase* child = body->FindObject(mjOBJ_BODY, std::string(name)); - if (!child) { - return 0; - } - return &(static_cast(child)->spec); + return child ? &(static_cast(child)->spec) : nullptr; } @@ -441,10 +472,16 @@ mjmBody* mjm_findChild(mjmBody* bodyspec, const char* name) { mjmMesh* mjm_findMesh(mjSpec* s, const char* name) { mjCModel* model = reinterpret_cast(s->element); mjCMesh* mesh = (mjCMesh*)model->FindObject(mjOBJ_MESH, std::string(name)); - if (!mesh) { - return nullptr; - } - return &(static_cast(mesh)->spec); + return mesh ? &(static_cast(mesh)->spec) : nullptr; +} + + + +// find frame by name +mjmFrame* mjm_findFrame(mjSpec* s, const char* name) { + mjCModel* model = reinterpret_cast(s->element); + mjCFrame* frame = (mjCFrame*)model->FindFrame(model->GetWorld(), std::string(name)); + return frame ? &(static_cast(frame)->spec) : nullptr; } diff --git a/src/user/user_api.h b/src/user/user_api.h index d5ffb06b..3e79c1c8 100644 --- a/src/user/user_api.h +++ b/src/user/user_api.h @@ -740,6 +740,10 @@ MJAPI void mjm_copyBack(mjSpec* s, const mjModel* m); // Compile model. MJAPI mjModel* mjm_compile(mjSpec* s, const mjVFS* vfs); +// Attach child body to a frame of the parent, return 0 if success +MJAPI int mjm_attachBody(mjmFrame* parent, const mjmBody* child, + const char* prefix, const char* suffix); + // Get error message from model. MJAPI const char* mjm_getError(mjSpec* s); @@ -860,6 +864,9 @@ MJAPI mjmBody* mjm_findChild(mjmBody* body, const char* name); // Find mesh by name. MJAPI mjmMesh* mjm_findMesh(mjSpec* s, const char* name); +// Find frame by name. +MJAPI mjmFrame* mjm_findFrame(mjSpec* s, const char* name); + // Get element id. MJAPI int mjm_getId(mjElement element); diff --git a/src/user/user_model.cc b/src/user/user_model.cc index 89960178..7c3fb4e6 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -162,6 +162,26 @@ mjCModel& mjCModel::operator=(const mjCModel& other) { this->spec = other.spec; *static_cast(this) = static_cast(other); *static_cast(this) = static_cast(other); + + // the world copy constructor takes care of copying the tree + mjCBody* world = new mjCBody(*other.bodies[0], this); + bodies.push_back(world); + + // add everything else + *this += other; + + // copy name maps + for (int i=0; i def_map; for (int i = 0; i < other.defaults.size(); i++) { defaults.push_back(new mjCDef(*other.defaults[i])); @@ -252,11 +272,7 @@ mjCModel& mjCModel::operator=(const mjCModel& other) { plugins = other.plugins; active_plugins = other.active_plugins; - // the world copy constructor takes care of copying the tree - mjCBody* world = new mjCBody(*other.bodies[0], this); - // create global lists - bodies.push_back(world); MakeLists(bodies[0]); // update defaults for the copied objects @@ -279,16 +295,12 @@ mjCModel& mjCModel::operator=(const mjCModel& other) { lights[i]->def = defaults[def_map[other.lights[i]->def]]; } - // copy name maps - for (int i=0; iname == name) { + return body; + } + + for (auto child : body->bodies) { + auto candidate = FindBody(child, name); + if (candidate) { + return candidate; + } + } + + return nullptr; +} + + + +// find frame by name +mjCFrame* mjCModel::FindFrame(mjCBody* body, std::string name) { + for (auto frame : body->frames) { + if (frame->name == name) { + return frame; + } + } + + for (auto body : body->bodies) { + auto candidate = FindFrame(body, name); + if (candidate) { + return candidate; + } + } + + return nullptr; +} + + + // detect null pose bool mjCModel::IsNullPose(const mjtNum* pos, const mjtNum* quat) { bool result = true; diff --git a/src/user/user_model.h b/src/user/user_model.h index 01b9b962..d6c1933f 100644 --- a/src/user/user_model.h +++ b/src/user/user_model.h @@ -154,6 +154,7 @@ class mjCModel : public mjCModel_, private mjSpec { mjCModel(); mjCModel(const mjCModel& other); mjCModel& operator=(const mjCModel& other); + mjCModel& operator+=(const mjCModel& other); ~mjCModel(); void CopyFromSpec(); // copy spec to private attributes void PointToLocal(); @@ -202,6 +203,8 @@ class mjCModel : public mjCModel_, private mjSpec { mjCDef* FindDef(std::string name); // find default class name mjCDef* AddDef(std::string name, int parentid); // add default class to array mjCBase* FindObject(mjtObj type, std::string name); // find object given type and name + mjCBody* FindBody(mjCBody* body, std::string name); // find body given name + mjCFrame* FindFrame(mjCBody* body, std::string name); // find frame given name bool IsNullPose(const mjtNum* pos, const mjtNum* quat); // detect null pose // accessors diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index adc45bc5..e4f3c744 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -683,6 +683,7 @@ mjCBody& mjCBody::operator=(const mjCBody& other) { for (int i=0; imodel = model; + frames.back()->body = this; fmap[other.frames[i]] = i; } @@ -731,6 +732,13 @@ mjCBody& mjCBody::operator=(const mjCBody& other) { +mjCBody& mjCBody::operator+=(mjCBody& other) { + bodies.push_back(&other); + return *this; +} + + + void mjCBody::PointToLocal() { spec.element = (mjElement)this; spec.name = (mjString)&name; @@ -784,6 +792,21 @@ mjCBody::~mjCBody() { +// apply prefix and suffix, propagate to children +void mjCBody::SetNameSpace() { + if (!name.empty()) { + name = prefix + name + suffix; + } + + for (auto& body : bodies) { + body->prefix = prefix; + body->suffix = suffix; + body->SetNameSpace(); + } +} + + + // create child body and add it to body mjCBody* mjCBody::AddBody(mjCDef* _def) { // create body @@ -1317,6 +1340,7 @@ mjCFrame::mjCFrame(mjCModel* _model, mjCFrame* _frame) { mjm_defaultFrame(spec); compiled = false; model = _model; + body = NULL; frame = _frame ? _frame : NULL; PointToLocal(); CopyFromSpec(); @@ -1341,6 +1365,27 @@ mjCFrame& mjCFrame::operator=(const mjCFrame& other) { } +// attach body to frame +mjCFrame& mjCFrame::operator+=(const mjCBody& other) { + mjCBody* subtree = new mjCBody(other, model); + subtree->SetFrame(this); + subtree->SetNameSpace(); + + // add to tree + *body += *subtree; + + // TODO: needs to attach only referencing elements + *model += *other.model; + return *this; +} + + + +void mjCFrame::SetParent(mjCBody* _body) { + body = _body; +} + + void mjCFrame::PointToLocal() { spec.element = (mjElement)this; diff --git a/src/user/user_objects.h b/src/user/user_objects.h index f553df97..50ae9f2e 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -173,10 +173,12 @@ class mjCBoundingVolumeHierarchy : public mjCBoundingVolumeHierarchy_ { class mjCBase_ { public: - std::string name; // object name - std::string classname; // defaults class name - int id; // object id - std::string info; // error message info set by the user + int id; // object id + std::string name; // object name + std::string classname; // defaults class name + std::string info; // error message info set by the user + std::string prefix; // prefix for model operations + std::string suffix; // suffix for model operations }; class mjCBase : public mjCBase_ { @@ -251,6 +253,7 @@ class mjCBody : public mjCBody_, private mjmBody { friend class mjCSite; friend class mjCCamera; friend class mjCComposite; + friend class mjCFrame; friend class mjCLight; friend class mjCFlex; friend class mjCFlexcomp; @@ -272,11 +275,17 @@ class mjCBody : public mjCBody_, private mjmBody { mjCCamera* AddCamera(mjCDef* = 0); mjCLight* AddLight(mjCDef* = 0); + // API for adding existing objects to body + mjCBody& operator+=(mjCBody& other); + // API for accessing objects int NumObjects(mjtObj type); mjCBase* GetObject(mjtObj type, int id); mjCBase* FindObject(mjtObj type, std::string name, bool recursive = true); + // Propagate suffix and prefix to the whole tree + void SetNameSpace(); + // set explicitinertial to true void MakeInertialExplicit(); @@ -346,12 +355,18 @@ class mjCFrame : public mjCFrame_, private mjmFrame { void CopyFromSpec(void); void PointToLocal(void); + void SetParent(mjCBody* _body); + + mjCFrame& operator+=(const mjCBody& other); + mjCFrame& operator+=(const mjCFrame& other); private: mjCFrame(mjCModel* = 0, mjCFrame* = 0); // constructor mjCFrame(const mjCFrame& other); // copy constructor mjCFrame& operator=(const mjCFrame& other); // copy assignment void Compile(void); // compiler + + mjCBody* body; // body that owns the frame }; diff --git a/src/xml/xml.cc b/src/xml/xml.cc index cbad8379..e6919948 100644 --- a/src/xml/xml.cc +++ b/src/xml/xml.cc @@ -15,7 +15,7 @@ #include "xml/xml.h" #include -#include "user/user_api.h" +#include #if defined(__APPLE__) || defined(__FreeBSD__) #include @@ -29,6 +29,7 @@ #include "tinyxml2.h" +#include #include #include #include "cc/array_safety.h" @@ -399,3 +400,33 @@ mjSpec* mjParseXML(const char* filename, const mjVFS* vfs, return model; } + + +static void RegisterResourceProvider() { + // register string resource provider if not registered before + if (mjp_getResourceProvider("LoadModelFromString:") == nullptr) { + mjpResourceProvider resourceProvider; + mjp_defaultResourceProvider(&resourceProvider); + resourceProvider.prefix = "LoadModelFromString"; + resourceProvider.open = +[](mjResource* resource) { + resource->data = &(resource->name[strlen("LoadModelFromString:")]); + return 1; + }; + resourceProvider.read = + +[](mjResource* resource, const void** buffer) { + *buffer = resource->data; + return (int) strlen((const char*) resource->data); + }; + resourceProvider.close = +[](mjResource* resource) {}; + mjp_registerResourceProvider(&resourceProvider); + } +} + + +mjSpec* ParseSpecFromString(std::string_view xml, char* error, + int error_size, mjVFS* vfs) { + RegisterResourceProvider(); + std::string xml2 = {xml.begin(), xml.end()}; + std::string str = "LoadModelFromString:" + xml2; + return mjParseXML(str.c_str(), vfs, error, error_size); +} diff --git a/src/xml/xml.h b/src/xml/xml.h index 4e91abf3..71104a6c 100644 --- a/src/xml/xml.h +++ b/src/xml/xml.h @@ -29,5 +29,10 @@ std::string mjWriteXML(mjSpec* model, char* error, int error_sz); // Main parser function MJAPI mjSpec* mjParseXML(const char* filename, const mjVFS* vfs, char* error, int error_sz); +// Returns a newly-allocated mjSpec, loaded from the contents of xml. +// On failure returns nullptr and populates the error array if present. +MJAPI mjSpec* ParseSpecFromString(std::string_view xml, char* error = nullptr, + int error_size = 0, mjVFS* vfs = nullptr); + #endif // MUJOCO_SRC_XML_XML_H_ diff --git a/test/user/user_api_test.cc b/test/user/user_api_test.cc index de1f9186..d6aa0f87 100644 --- a/test/user/user_api_test.cc +++ b/test/user/user_api_test.cc @@ -195,5 +195,96 @@ TEST_F(PluginTest, RecompileCompareCache) { mj_deleteVFS(vfs.get()); } +// -------------------------------- test attach ------------------------------- +TEST_F(MujocoTest, Attach) { + std::array er; + mjtNum tol = 0; + std::string field = ""; + + static constexpr char xml_parent[] = R"( + + + + + + + + + )"; + + static constexpr char xml_child[] = R"( + + + + + + + + + + )"; + + static constexpr char xml_result[] = R"( + + + + + + + + + + + + + + + + )"; + + // model with one free sphere and a frame + mjSpec* parent = ParseSpecFromString(xml_parent, er.data(), er.size()); + EXPECT_THAT(parent, NotNull()) << er.data(); + + // get frame + mjmFrame* frame = mjm_findFrame(parent, "frame"); + EXPECT_THAT(frame, NotNull()); + + // model with one cylinder and a hinge + mjSpec* child = ParseSpecFromString(xml_child, er.data(), er.size()); + EXPECT_THAT(child, NotNull()) << er.data(); + + // get subtree + mjmBody* body = mjm_findBody(child, "cylinder"); + EXPECT_THAT(body, NotNull()); + + // attach child to parent frame + EXPECT_THAT( + mjm_attachBody(frame, body, /*prefix=*/"attached-", /*suffix=*/"-1"), 0); + + // compile new model + mjModel* m_attached = mjm_compile(parent, 0); + EXPECT_THAT(m_attached, NotNull()); + + // check full name stored in mjModel + EXPECT_STREQ(mj_id2name(m_attached, mjOBJ_BODY, 2), "attached-cylinder-1"); + + // check body 2 is attached to body 1 + EXPECT_THAT(m_attached->body_parentid[2], 1); + + // compare with expected XML + mjModel* m_expected = LoadModelFromString(xml_result, er.data(), er.size()); + EXPECT_THAT(m_expected, NotNull()) << er.data(); + EXPECT_LE(CompareModel(m_attached, m_expected, field), tol) + << "Expected and attached models are different!\n" + << "Different field: " << field << '\n';; + + // destroy everything + mjm_deleteSpec(parent); + mjm_deleteSpec(child); + mj_deleteModel(m_attached); + mj_deleteModel(m_expected); +} + } // namespace } // namespace mujoco From b4694ee331e85d789a51651378a4a05f0367d3bc Mon Sep 17 00:00:00 2001 From: Baruch Tabanpour Date: Tue, 19 Mar 2024 14:35:13 -0700 Subject: [PATCH 22/51] Fix bug in MJX viewer. PiperOrigin-RevId: 617297574 Change-Id: I34fb797db47308a8b2f29a6c54f2b59d77f84a32 --- mjx/mujoco/mjx/_src/io.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mjx/mujoco/mjx/_src/io.py b/mjx/mujoco/mjx/_src/io.py index 1958829f..d290a612 100644 --- a/mjx/mujoco/mjx/_src/io.py +++ b/mjx/mujoco/mjx/_src/io.py @@ -239,6 +239,7 @@ def _get_contact( ncon = cx.dist.shape[0] c.efc_address[:] = np.arange(efc_start, efc_start + ncon * 4, 4)[con_id] + c.dim[:] = 3 def get_data( From 20c8e3e43b74c625a82e4494f62ef0d01f3bed4b Mon Sep 17 00:00:00 2001 From: Matthew Bennice Date: Tue, 19 Mar 2024 14:51:47 -0700 Subject: [PATCH 23/51] Implement basic USD test PiperOrigin-RevId: 617302442 Change-Id: Ic598df9757288640b5f35c4e740958884b1b4698 --- python/mujoco/testdata/usd_golden.usda | 71 ++++++++++++++++++++++++++ python/mujoco/usd/component.py | 66 +++++++++++------------- python/mujoco/usd/exporter.py | 36 +++++++------ python/mujoco/usd/exporter_test.py | 70 +++++++++++++++++++++++++ 4 files changed, 192 insertions(+), 51 deletions(-) create mode 100644 python/mujoco/testdata/usd_golden.usda create mode 100644 python/mujoco/usd/exporter_test.py diff --git a/python/mujoco/testdata/usd_golden.usda b/python/mujoco/testdata/usd_golden.usda new file mode 100644 index 00000000..1a154486 --- /dev/null +++ b/python/mujoco/testdata/usd_golden.usda @@ -0,0 +1,71 @@ +#usda 1.0 +( + defaultPrim = "World" + doc = """Generated from Composed Stage of root layer +""" + endTimeCode = 1 + startTimeCode = 0 + timeCodesPerSecond = 24 + upAxis = "Z" +) + +def Xform "World" +{ + def Xform "Light_Xform_0" + { + double3 xformOp:translate + uniform token[] xformOpOrder = ["xformOp:translate"] + + def SphereLight "Light_0" + { + bool inputs:normalize = 1 + float inputs:radius = 0.3 + bool treatAsPoint = 0 + } + } + + def Xform "CubeMesh_Xform_white_box" + { + matrix4d xformOp:transform.timeSamples = { + 0: ( (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 0), (0, 0, 0, 1) ), + } + uniform token[] xformOpOrder = ["xformOp:transform"] + + def Mesh "CubeMesh_white_box" ( + apiSchemas = ["MaterialBindingAPI"] + ) + { + int[] faceVertexCounts = [3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3] + int[] faceVertexIndices = [4, 7, 5, 4, 6, 7, 0, 2, 4, 2, 6, 4, 0, 1, 2, 1, 3, 2, 1, 5, 7, 1, 7, 3, 2, 3, 7, 2, 7, 6, 0, 4, 1, 1, 4, 5] + rel material:binding = + point3f[] points = [(-1, -1, -1), (1, -1, -1), (-1, -1, 1), (1, -1, 1), (-1, 1, -1), (1, 1, -1), (-1, 1, 1), (1, 1, 1)] + texCoord2f[] primvars:UVMap = [] ( + interpolation = "faceVarying" + ) + int[] primvars:UVMap:indices = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35] + uniform token subdivisionScheme = "none" + token visibility.timeSamples = { + 0: "inherited", + } + } + } + + def "_materials" + { + def Material "Material_white_box" + { + token outputs:surface.connect = + + def Shader "Principled_BSDF" + { + uniform token info:id = "UsdPreviewSurface" + color3f inputs:diffuseColor = (1, 1, 1) + float inputs:metallic = 0.5 + float inputs:opacity = 1 + float inputs:roughness = 0.5 + token outputs:surface + } + } + } +} + diff --git a/python/mujoco/usd/component.py b/python/mujoco/usd/component.py index 02707a13..c8a80f6f 100644 --- a/python/mujoco/usd/component.py +++ b/python/mujoco/usd/component.py @@ -15,6 +15,7 @@ from typing import List, Optional, Tuple import mujoco +import mujoco.usd.utils import numpy as np # TODO: b/288149332 - Remove once USD Python Binding works well with pytype. @@ -36,9 +37,9 @@ class USDMesh: stage: Usd.Stage, model: mujoco.MjModel, geom: mujoco.MjvGeom, - objid: int, + objid: str, dataid: int, - rgba: Tuple[int, ...] = (1, 1, 1, 1), + rgba: np.ndarray = np.array([1, 1, 1, 1]), texture_file: Optional[str] = None, ): self.stage = stage @@ -216,7 +217,7 @@ class USDMesh: UsdShade.MaterialBindingAPI(self.usd_mesh).Bind(mtl) def update(self, pos: np.ndarray, mat: np.ndarray, visible: bool, frame: int): - transformation_mat = mujoco.usd_utils.create_transform_matrix( + transformation_mat = mujoco.usd.utils.create_transform_matrix( rotation_matrix=mat, translation_vector=pos ).T self.transform_op.Set(Gf.Matrix4d(transformation_mat.tolist()), frame) @@ -235,8 +236,8 @@ class USDPrimitiveMesh: self, stage: Usd.Stage, geom: mujoco.MjvGeom, - objid: int, - rgba: Tuple[int, ...] = (1, 1, 1, 1), + objid: str, + rgba: np.ndarray = np.array([1, 1, 1, 1]), texture_file: Optional[str] = None, ): self.stage = stage @@ -246,9 +247,9 @@ class USDPrimitiveMesh: self.texture_file = texture_file self.usd_prim = Usd.Prim() - self.usd_mesh = Usd.Mesh() - self.prim_mesh = Usd.PrimMesh() - self.transform_op = Usd.TransformOp() + self.usd_mesh = UsdGeom.Mesh() + self.prim_mesh = None + self.transform_op = Gf.Matrix4d(1.) def _set_refinement_properties(self): self.usd_prim.GetAttribute("subdivisionScheme").Set("none") @@ -364,7 +365,7 @@ class USDPrimitiveMesh: UsdShade.MaterialBindingAPI(self.usd_mesh).Bind(mtl) def update(self, pos: np.ndarray, mat: np.ndarray, visible: bool, frame: int): - transformation_mat = mujoco.usd_util.create_transform_matrix( + transformation_mat = mujoco.usd.utils.create_transform_matrix( rotation_matrix=mat, translation_vector=pos ).T self.transform_op.Set(Gf.Matrix4d(transformation_mat.tolist()), frame) @@ -383,8 +384,8 @@ class USDPrimitive: self, stage: Usd.Stage, geom: mujoco.MjvGeom, - objid: int, - rgba: Tuple[int, ...] = (1, 1, 1, 1), + objid: str, + rgba: np.ndarray = np.array([1, 1, 1, 1]), texture_file: Optional[str] = None, ): self.stage = stage @@ -395,7 +396,7 @@ class USDPrimitive: self.usd_prim = Usd.Prim() self.usd_primitive_shape = Usd.PrimitiveShape() - self.transform_op = Usd.TransformOp() + self.transform_op = Gf.Matrix4d(1.) def _set_refinement_properties(self): self.usd_prim.GetAttribute("subdivisionScheme").Set("none") @@ -481,7 +482,7 @@ class USDPrimitive: UsdShade.MaterialBindingAPI(self.usd_primitive_shape).Bind(mtl) def update(self, pos: np.ndarray, mat: np.ndarray, visible: bool, frame: int): - transformation_mat = mujoco.usd_util.create_transform_matrix( + transformation_mat = mujoco.usd.utils.create_transform_matrix( rotation_matrix=mat, translation_vector=pos ).T self.transform_op.Set(Gf.Matrix4d(transformation_mat.tolist()), frame) @@ -500,8 +501,8 @@ class USDCapsule(USDPrimitive): self, stage: Usd.Stage, geom: mujoco.MjvGeom, - objid: int, - rgba: Tuple[int, ...] = (1, 1, 1, 1), + objid: str, + rgba: np.ndarray = np.array([1, 1, 1, 1]), texture_file: Optional[str] = None, ): @@ -536,8 +537,8 @@ class USDEllipsoid(USDPrimitive): self, stage: Usd.Stage, geom: mujoco.MjvGeom, - objid: int, - rgba: Tuple[int, ...] = (1, 1, 1, 1), + objid: str, + rgba: np.ndarray = np.array([1, 1, 1, 1]), texture_file: Optional[str] = None, ): @@ -569,8 +570,8 @@ class USDCubeMesh(USDPrimitiveMesh): self, stage: Usd.Stage, geom: mujoco.MjvGeom, - objid: int, - rgba: Tuple[int, ...] = (1, 1, 1, 1), + objid: str, + rgba: np.ndarray = np.array([1, 1, 1, 1]), texture_file: Optional[str] = None, ): @@ -586,8 +587,6 @@ class USDCubeMesh(USDPrimitiveMesh): width=self.geom.size[0] * 2, height=self.geom.size[1] * 2, depth=self.geom.size[2] * 2, - create_uv_map=True, - map_texture_to_each_face=True, ) self.prim_mesh.translate(-self.prim_mesh.get_center()) @@ -623,8 +622,8 @@ class USDSphereMesh(USDPrimitiveMesh): self, stage: Usd.Stage, geom: mujoco.MjvGeom, - objid: int, - rgba: Tuple[int, ...] = (1, 1, 1, 1), + objid: str, + rgba: np.ndarray = np.array([1, 1, 1, 1]), texture_file: Optional[str] = None, ): @@ -637,7 +636,7 @@ class USDSphereMesh(USDPrimitiveMesh): self.usd_prim = stage.GetPrimAtPath(mesh_path) self.prim_mesh = o3d.geometry.TriangleMesh.create_sphere( - radius=float(self.geom.size[0]), create_uv_map=True + radius=float(self.geom.size[0]) ) self.prim_mesh.translate(-self.prim_mesh.get_center()) @@ -673,8 +672,8 @@ class USDCylinderMesh(USDPrimitiveMesh): self, stage: Usd.Stage, geom: mujoco.MjvGeom, - objid: int, - rgba: Tuple[int, ...] = (1, 1, 1, 1), + objid: str, + rgba: np.ndarray = np.array([1, 1, 1, 1]), texture_file: Optional[str] = None, ): @@ -689,7 +688,6 @@ class USDCylinderMesh(USDPrimitiveMesh): self.prim_mesh = o3d.geometry.TriangleMesh.create_cylinder( radius=self.geom.size[0], height=self.geom.size[2] * 2, - create_uv_map=True, ) self.prim_mesh.translate(-self.prim_mesh.get_center()) @@ -725,8 +723,8 @@ class USDPlaneMesh(USDPrimitiveMesh): self, stage: Usd.Stage, geom: mujoco.MjvGeom, - objid: int, - rgba: Tuple[int, ...] = (1, 1, 1, 1), + objid: str, + rgba: np.ndarray = np.array([1, 1, 1, 1]), texture_file: Optional[str] = None, ): @@ -742,8 +740,6 @@ class USDPlaneMesh(USDPrimitiveMesh): width=self.geom.size[0] * 2 if self.geom.size[0] > 0 else 100, height=self.geom.size[1] * 2 if self.geom.size[1] > 0 else 100, depth=0.001, - create_uv_map=True, - map_texture_to_each_face=True, ) self.prim_mesh.translate(-self.prim_mesh.get_center()) @@ -776,7 +772,7 @@ class USDPlaneMesh(USDPrimitiveMesh): class USDSphereLight: def __init__( - self, stage: Usd.Stage, objid: int, radius: Optional[float] = 0.3 + self, stage: Usd.Stage, objid: str, radius: Optional[float] = 0.3 ): self.stage = stage @@ -808,7 +804,7 @@ class USDSphereLight: class USDDomeLight: - def __init__(self, stage: Usd.Stage, objid: int): + def __init__(self, stage: Usd.Stage, objid: str): self.stage = stage xform_path = f"/World/Light_Xform_{objid}" @@ -829,7 +825,7 @@ class USDDomeLight: class USDCamera: - def __init__(self, stage: Usd.Stage, objid: int): + def __init__(self, stage: Usd.Stage, objid: str): self.stage = stage xform_path = f"/World/Camera_Xform_{objid}" @@ -851,7 +847,7 @@ class USDCamera: def update(self, cam_pos: np.ndarray, cam_mat: np.ndarray, frame: int): - transformation_mat = mujoco.usd_util.create_transform_matrix( + transformation_mat = mujoco.usd.utils.create_transform_matrix( rotation_matrix=cam_mat, translation_vector=cam_pos ).T self.transform_op.Set(Gf.Matrix4d(transformation_mat.tolist()), frame) diff --git a/python/mujoco/usd/exporter.py b/python/mujoco/usd/exporter.py index c45979ef..4ec94bf6 100644 --- a/python/mujoco/usd/exporter.py +++ b/python/mujoco/usd/exporter.py @@ -15,6 +15,7 @@ import os import mujoco +import mujoco.usd.component as component_module import numpy as np import scipy import termcolor @@ -235,7 +236,7 @@ class USDExporter: # handles meshes in scene if geom.type == mujoco.mjtGeom.mjGEOM_MESH: - usd_geom = mujoco.usd.USDMesh( + usd_geom = component_module.USDMesh( stage=self.stage, model=self.model, geom=geom, @@ -245,7 +246,7 @@ class USDExporter: texture_file=texture_file, ) elif geom.type == mujoco.mjtGeom.mjGEOM_PLANE: - usd_geom = mujoco.usd.USDPlaneMesh( + usd_geom = component_module.USDPlaneMesh( stage=self.stage, geom=geom, objid=geom_name, @@ -253,7 +254,7 @@ class USDExporter: texture_file=texture_file, ) elif geom.type == mujoco.mjtGeom.mjGEOM_SPHERE: - usd_geom = mujoco.usd.USDSphereMesh( + usd_geom = component_module.USDSphereMesh( stage=self.stage, geom=geom, objid=geom_name, @@ -261,7 +262,7 @@ class USDExporter: texture_file=texture_file, ) elif geom.type == mujoco.mjtGeom.mjGEOM_CAPSULE: - usd_geom = mujoco.usd.USDCapsule( + usd_geom = component_module.USDCapsule( stage=self.stage, geom=geom, objid=geom_name, @@ -269,7 +270,7 @@ class USDExporter: texture_file=texture_file, ) elif geom.type == mujoco.mjtGeom.mjGEOM_ELLIPSOID: - usd_geom = mujoco.usd.USDEllipsoid( + usd_geom = component_module.USDEllipsoid( stage=self.stage, geom=geom, objid=geom_name, @@ -277,7 +278,7 @@ class USDExporter: texture_file=texture_file, ) elif geom.type == mujoco.mjtGeom.mjGEOM_CYLINDER: - usd_geom = mujoco.usd.USDCylinderMesh( + usd_geom = component_module.USDCylinderMesh( stage=self.stage, geom=geom, objid=geom_name, @@ -285,7 +286,7 @@ class USDExporter: texture_file=texture_file, ) elif geom.type == mujoco.mjtGeom.mjGEOM_BOX: - usd_geom = mujoco.usd.USDCubeMesh( + usd_geom = component_module.USDCubeMesh( stage=self.stage, geom=geom, objid=geom_name, @@ -331,7 +332,8 @@ class USDExporter: for i in range(self.scene.nlight): light = self.scene.lights[i] if not np.allclose(light.pos, [0, 0, 0]): - self.usd_lights.append(mujoco.usd.USDSphereLight(stage=self.stage, objid=i)) + self.usd_lights.append + (component_module.USDSphereLight(stage=self.stage, objid=str(i))) else: self.usd_lights.append(None) @@ -342,7 +344,7 @@ class USDExporter: if np.allclose(light.pos, [0, 0, 0]): continue - if self.usd_lights[i] is None: + if i >= len(self.usd_lights) or self.usd_lights[i] is None: continue self.usd_lights[i].update( @@ -356,8 +358,10 @@ class USDExporter: def _load_cameras(self): self.usd_cameras = [] - for name in self.camera_names: - self.usd_cameras.append(mujoco.usd.USDCamera(stage=self.stage, objid=name)) + if self.camera_names is not None: + for name in self.camera_names: + self.usd_cameras.append( + component_module.USDCamera(stage=self.stage, objid=name)) def _update_cameras( self, @@ -397,11 +401,11 @@ class USDExporter: ): if light_type == "sphere": - new_light = mujoco.usd.USDSphereLight(stage=self.stage, objid=objid, radius=radius) + new_light = component_module.USDSphereLight(stage=self.stage, objid=str(objid), radius=radius) - new_light.update(pos=pos, intensity=intensity, color=color, frame=0) + new_light.update(pos=np.array(pos), intensity=intensity, color=color, frame=0) elif light_type == "dome": - new_light = mujoco.usd.USDDomeLight(stage=self.stage, objid=objid) + new_light = component_module.USDDomeLight(stage=self.stage, objid=str(objid)) new_light.update(intensity=intensity, color=color, frame=0) @@ -411,11 +415,11 @@ class USDExporter: rotation_xyz: List[float], objid: Optional[int] = 1, ): - new_camera = mujoco.usd.USDCamera(stage=self.stage, objid=objid) + new_camera = component_module.USDCamera(stage=self.stage, objid=str(objid)) r = scipy.spatial.transform.Rotation.from_euler( "xyz", rotation_xyz, degrees=True) - new_camera.update(cam_pos=pos, cam_mat=r.as_matrix(), frame=0) + new_camera.update(cam_pos=np.array(pos), cam_mat=r.as_matrix(), frame=0) def save_scene(self, filetype: str = "usd"): self.stage.SetEndTimeCode(self.frame_count) diff --git a/python/mujoco/usd/exporter_test.py b/python/mujoco/usd/exporter_test.py new file mode 100644 index 00000000..17d6e855 --- /dev/null +++ b/python/mujoco/usd/exporter_test.py @@ -0,0 +1,70 @@ +# Copyright 2024 DeepMind Technologies Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for the MuJoCo USD Exporter.""" + +import logging +import os + +import mujoco + +from absl.testing import absltest +from etils import epath + +# Open3D and USD are not fully supported on all MuJoCo architectures. +# pylint: disable=python.style(g-import-not-at-top) +execute_test = True +try: + from mujoco.usd import exporter as exporter_module + from pxr import Usd +except ImportError: + logging.warning('Skipping test due to missing import') + execute_test = False +# pylint: enable=python.style(g-import-not-at-top) + +class ExporterTest(absltest.TestCase): + + def test_usd_export(self): + if not execute_test: + return + + output_dir = os.getenv('TEST_UNDECLARED_OUTPUTS_DIR') + xml = """ + + + + + + +""" + model = mujoco.MjModel.from_xml_string(xml) + data = mujoco.MjData(model) + exporter = exporter_module.USDExporter( + model, + output_directory_name="mujoco_usdpkg", + output_directory_root=output_dir, + ) + exporter.update_scene(data) + exporter.save_scene("export.usda") + + with open(os.path.join( + output_dir, "mujoco_usdpkg/frames", "frame_1_.export.usda"), "r") as f: + golden_path = os.path.join( + epath.resource_path("mujoco"), "testdata", "usd_golden.usda") + with open(golden_path, "r") as golden_file: + self.assertEqual(f.read(), golden_file.read()) + + +if __name__ == "__main__": + absltest.main() From 9b86329797708cb467f675e09eb1ffd78bdbf305 Mon Sep 17 00:00:00 2001 From: Erik Frey Date: Tue, 19 Mar 2024 15:47:40 -0700 Subject: [PATCH 24/51] Add 01-10 humanoids for benchmarking. PiperOrigin-RevId: 617318016 Change-Id: Ic5dc0623266d4d6bef6da97d03370010e2817a2a --- .../mjx/test_data/humanoid/01_humanoids.xml | 150 +++ .../mjx/test_data/humanoid/02_humanoids.xml | 255 ++++ .../mjx/test_data/humanoid/03_humanoids.xml | 359 ++++++ .../mjx/test_data/humanoid/04_humanoids.xml | 463 +++++++ .../mjx/test_data/humanoid/05_humanoids.xml | 567 +++++++++ .../mjx/test_data/humanoid/06_humanoids.xml | 671 ++++++++++ .../mjx/test_data/humanoid/07_humanoids.xml | 775 ++++++++++++ .../mjx/test_data/humanoid/08_humanoids.xml | 879 +++++++++++++ .../mjx/test_data/humanoid/09_humanoids.xml | 983 +++++++++++++++ .../mjx/test_data/humanoid/10_humanoids.xml | 1087 +++++++++++++++++ 10 files changed, 6189 insertions(+) create mode 100644 mjx/mujoco/mjx/test_data/humanoid/01_humanoids.xml create mode 100644 mjx/mujoco/mjx/test_data/humanoid/02_humanoids.xml create mode 100644 mjx/mujoco/mjx/test_data/humanoid/03_humanoids.xml create mode 100644 mjx/mujoco/mjx/test_data/humanoid/04_humanoids.xml create mode 100644 mjx/mujoco/mjx/test_data/humanoid/05_humanoids.xml create mode 100644 mjx/mujoco/mjx/test_data/humanoid/06_humanoids.xml create mode 100644 mjx/mujoco/mjx/test_data/humanoid/07_humanoids.xml create mode 100644 mjx/mujoco/mjx/test_data/humanoid/08_humanoids.xml create mode 100644 mjx/mujoco/mjx/test_data/humanoid/09_humanoids.xml create mode 100644 mjx/mujoco/mjx/test_data/humanoid/10_humanoids.xml diff --git a/mjx/mujoco/mjx/test_data/humanoid/01_humanoids.xml b/mjx/mujoco/mjx/test_data/humanoid/01_humanoids.xml new file mode 100644 index 00000000..a8aa807f --- /dev/null +++ b/mjx/mujoco/mjx/test_data/humanoid/01_humanoids.xml @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mjx/mujoco/mjx/test_data/humanoid/02_humanoids.xml b/mjx/mujoco/mjx/test_data/humanoid/02_humanoids.xml new file mode 100644 index 00000000..f41ecabf --- /dev/null +++ b/mjx/mujoco/mjx/test_data/humanoid/02_humanoids.xml @@ -0,0 +1,255 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mjx/mujoco/mjx/test_data/humanoid/03_humanoids.xml b/mjx/mujoco/mjx/test_data/humanoid/03_humanoids.xml new file mode 100644 index 00000000..f855f790 --- /dev/null +++ b/mjx/mujoco/mjx/test_data/humanoid/03_humanoids.xml @@ -0,0 +1,359 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mjx/mujoco/mjx/test_data/humanoid/04_humanoids.xml b/mjx/mujoco/mjx/test_data/humanoid/04_humanoids.xml new file mode 100644 index 00000000..ff6cb712 --- /dev/null +++ b/mjx/mujoco/mjx/test_data/humanoid/04_humanoids.xml @@ -0,0 +1,463 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mjx/mujoco/mjx/test_data/humanoid/05_humanoids.xml b/mjx/mujoco/mjx/test_data/humanoid/05_humanoids.xml new file mode 100644 index 00000000..d6483316 --- /dev/null +++ b/mjx/mujoco/mjx/test_data/humanoid/05_humanoids.xml @@ -0,0 +1,567 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mjx/mujoco/mjx/test_data/humanoid/06_humanoids.xml b/mjx/mujoco/mjx/test_data/humanoid/06_humanoids.xml new file mode 100644 index 00000000..aa3cc960 --- /dev/null +++ b/mjx/mujoco/mjx/test_data/humanoid/06_humanoids.xml @@ -0,0 +1,671 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mjx/mujoco/mjx/test_data/humanoid/07_humanoids.xml b/mjx/mujoco/mjx/test_data/humanoid/07_humanoids.xml new file mode 100644 index 00000000..a6f68187 --- /dev/null +++ b/mjx/mujoco/mjx/test_data/humanoid/07_humanoids.xml @@ -0,0 +1,775 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mjx/mujoco/mjx/test_data/humanoid/08_humanoids.xml b/mjx/mujoco/mjx/test_data/humanoid/08_humanoids.xml new file mode 100644 index 00000000..b1d605d6 --- /dev/null +++ b/mjx/mujoco/mjx/test_data/humanoid/08_humanoids.xml @@ -0,0 +1,879 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mjx/mujoco/mjx/test_data/humanoid/09_humanoids.xml b/mjx/mujoco/mjx/test_data/humanoid/09_humanoids.xml new file mode 100644 index 00000000..bbec2355 --- /dev/null +++ b/mjx/mujoco/mjx/test_data/humanoid/09_humanoids.xml @@ -0,0 +1,983 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mjx/mujoco/mjx/test_data/humanoid/10_humanoids.xml b/mjx/mujoco/mjx/test_data/humanoid/10_humanoids.xml new file mode 100644 index 00000000..6bcae8ec --- /dev/null +++ b/mjx/mujoco/mjx/test_data/humanoid/10_humanoids.xml @@ -0,0 +1,1087 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 07da7336e816d73849eab76909dbb9657c15fef2 Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Wed, 20 Mar 2024 01:14:57 -0700 Subject: [PATCH 25/51] Set mesh visual flag regardless of discardvisual. PiperOrigin-RevId: 617428859 Change-Id: I427d888e6caa2fe1ae6597ca7165c600c9779cc7 --- src/user/user_mesh.cc | 1 + src/user/user_model.cc | 19 +++++-------------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/user/user_mesh.cc b/src/user/user_mesh.cc index 59aad976..c85e3cd9 100644 --- a/src/user/user_mesh.cc +++ b/src/user/user_mesh.cc @@ -432,6 +432,7 @@ void mjCMesh::LoadSDF() { // compiler void mjCMesh::Compile(const mjVFS* vfs) { CopyFromSpec(); + visual_ = true; // load file if (!file_.empty()) { diff --git a/src/user/user_model.cc b/src/user/user_model.cc index 7c3fb4e6..8728b5e6 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -983,21 +983,12 @@ void mjCModel::IndexAssets(bool discard) { // find mesh by name if (!pgeom->get_meshname().empty()) { - mjCBase* m = FindObject(mjOBJ_MESH, pgeom->get_meshname()); - if (m) { - if (discard && geoms[i]->visual_) { - // do not associate with a mesh - pgeom->mesh = nullptr; - } else { - // associate mesh with geom - pgeom->mesh = (mjCMesh*)m; - - // mark mesh as not visual - // this is irreversible so only performed when IndexAssets is called with discard - if (discard) { - pgeom->mesh->SetNotVisual(); - } + mjCBase* pmesh = FindObject(mjOBJ_MESH, pgeom->get_meshname()); + if (pmesh) { + if (!pgeom->visual_) { + ((mjCMesh*)pmesh)->SetNotVisual(); // reset to true by mesh->Compile() } + pgeom->mesh = (discard && pgeom->visual_) ? nullptr : (mjCMesh*)pmesh; } else { throw mjCError(pgeom, "mesh '%s' not found in geom %d", pgeom->get_meshname().c_str(), i); } From 624becca52d38de8fbda48ac62c2209a527631d1 Mon Sep 17 00:00:00 2001 From: Baruch Tabanpour Date: Wed, 20 Mar 2024 15:44:37 -0700 Subject: [PATCH 26/51] Fix some more bugs in sphere/capsule-convex collisions. PiperOrigin-RevId: 617646119 Change-Id: Ie0c99ccbe1dd2a18663d45a111e77fed4112e638 --- mjx/mujoco/mjx/_src/collision_convex.py | 110 +++++++++++-------- mjx/mujoco/mjx/_src/collision_driver_test.py | 68 +++++++++--- 2 files changed, 116 insertions(+), 62 deletions(-) diff --git a/mjx/mujoco/mjx/_src/collision_convex.py b/mjx/mujoco/mjx/_src/collision_convex.py index ce3e41e2..26eb5e8a 100644 --- a/mjx/mujoco/mjx/_src/collision_convex.py +++ b/mjx/mujoco/mjx/_src/collision_convex.py @@ -215,46 +215,47 @@ def sphere_convex(sphere: GeomInfo, convex: GeomInfo) -> Contact: return jp.dot(pos - faces[0], normal) support = get_support(faces, normals) + has_separating_axis = jp.any(support >= 0) - # Pick the face with minimal penetration as long as it has support. - support = jp.where(support >= 0, -1e12, support) + # Pick the face with the best separating axis. best_idx = support.argmax() face = faces[best_idx] - normal = normals[best_idx] + face_normal = normals[best_idx] # Get closest point between the polygon face and the sphere center point. # Project the sphere center point onto poly plane. If it's inside polygon - # edge normals, then we're done. - pt = _project_pt_onto_plane(sphere_pos, face[0], normal) + # side planes, then we're done. + pt = _project_pt_onto_plane(sphere_pos, face[0], face_normal) edge_p0 = jp.roll(face, 1, axis=0) edge_p1 = face - edge_normals = jax.vmap(jp.cross, in_axes=[0, None])( + side_normals = jax.vmap(jp.cross, in_axes=[0, None])( edge_p1 - edge_p0, - normal, + face_normal, ) edge_dist = jax.vmap( lambda plane_pt, plane_norm: (pt - plane_pt).dot(plane_norm) - )(edge_p0, edge_normals) - inside = jp.all(edge_dist <= 0) # lte to handle degenerate edges + )(edge_p0, side_normals) + pt_on_face = jp.all(edge_dist <= 0) # lte to handle degenerate edges - # If the point is outside edge normals, project onto the closest edge plane + # If the point is outside side planes, project onto the closest side plane # that the point is in front of. - degenerate_edge = jp.all(edge_normals == 0, axis=1) + degenerate_edge = jp.all(side_normals == 0, axis=1) behind = edge_dist < 0.0 edge_dist = jp.where(degenerate_edge | behind, 1e12, edge_dist) idx = edge_dist.argmin() edge_pt = math.closest_segment_point(edge_p0[idx], edge_p1[idx], pt) - - pt = jp.where(inside, pt, edge_pt) + pt = jp.where(pt_on_face, pt, edge_pt) # Get the normal, dist, and contact position. - n, d = math.normalize_with_norm(pt - sphere_pos) - n = jp.where(inside | (d < 1e-6), normal, n) + pt_normal, d = math.normalize_with_norm(pt - sphere_pos) # Ensure normal points towards convex centroid. - n *= jp.where(jp.dot(pt, n) < 0, 1, -1) + inside = jp.dot(pt, pt_normal) > 0 + sign = jp.where(inside, -1, 1) + n = jp.where(pt_on_face | (d < 1e-6), -face_normal, sign * pt_normal) + d *= sign spt = sphere_pos + n * sphere.size[0] - dist = d - sphere.size[0] + dist = jp.where(has_separating_axis, 1.0, d - sphere.size[0]) pos = (pt + spt) * 0.5 # Go back to world frame. @@ -292,8 +293,7 @@ def capsule_convex(cap: GeomInfo, convex: GeomInfo) -> Contact: support = get_support(faces, normals) has_support = jp.all(support < 0) - # Pick the face with minimal penetration as long as it has support. - support = jp.where(support >= 0, -1e12, support) + # Pick the face with minimal penetration. best_idx = support.argmax() face = faces[best_idx] normal = normals[best_idx] @@ -316,44 +316,64 @@ def capsule_convex(cap: GeomInfo, convex: GeomInfo) -> Contact: # Create variables for the face contact. pos = (cap_pts_clipped + face_pts) * 0.5 contact_normal = -jp.stack([normal] * 2, 0) - penetration = jp.where( + face_penetration = jp.where( mask & has_support, jp.dot(face_pts - cap_pts_clipped, normal), -1 ) - # Get a potential edge contact. - edge_closest, cap_closest = jax.vmap( - math.closest_segment_to_segment_points, - in_axes=[0, 0, None, None], - )(edge_p0, edge_p1, cap_pts[0], cap_pts[1]) - e_idx = ((edge_closest - cap_closest) ** 2).sum(axis=1).argmin() - cap_closest_pt, edge_closest_pt = cap_closest[e_idx], edge_closest[e_idx] - edge_dir = edge_closest_pt - cap_closest_pt - degenerate_edge_dir = jp.sum(jp.square(edge_dir)) < 1e-6 - edge_dir, edge_dist = math.normalize_with_norm(edge_dir) - face_edge_normals = convex.face_edge_normal[best_idx][e_idx] - inside_edge_voronoi_front = ((face_edge_normals @ edge_dir) < 0).all() - inside_edge_voronoi_back = ((face_edge_normals @ edge_dir) > 0).all() - outside_edge_voronoi = ~inside_edge_voronoi_front & ~inside_edge_voronoi_back - edge_axis = math.normalize(-edge_closest_pt) # approximate edge axis - edge_axis = jp.where( - ~degenerate_edge_dir & inside_edge_voronoi_front, - edge_dir, # shallow edge penetration - edge_axis, # deep edge penetration - ) + # Pick a potential shallow edge contact. + def get_edge_axis(edge): + edge_closest_pt, cap_closest_pt = math.closest_segment_to_segment_points( + edge[0], edge[1], cap_pts[0], cap_pts[1] + ) + edge_dir = edge_closest_pt - cap_closest_pt + degenerate_edge_dir = jp.sum(jp.square(edge_dir)) < 1e-6 + edge_axis, edge_dist = math.normalize_with_norm(edge_dir) + return ( + edge_dist, + edge_axis, + degenerate_edge_dir, + edge_closest_pt, + cap_closest_pt, + ) + + edge = jp.take(convex.vert, convex.face_edge, axis=0).reshape(-1, 2, 3) + face_edge_normal = convex.face_edge_normal.reshape((-1, 2, 3)) # pytype: disable=attribute-error + + res = jax.vmap(get_edge_axis)(edge.reshape(-1, 2, 3)) + e_idx = jp.abs(res[0]).argmin() + ( + edge_dist, + edge_axis, + degenerate_edge_dir, + edge_closest_pt, + cap_closest_pt, + ) = jax.tree_map(lambda x, i=e_idx: jp.take(x, i, axis=0), res) + + face_edge_normals = face_edge_normal[e_idx] + edge_voronoi_front = ((face_edge_normals @ edge_axis) < 0).all() + shallow = ~degenerate_edge_dir & edge_voronoi_front + edge_penetration = jp.where(shallow, cap.size[0] - edge_dist, -1) # Determine edge contact position. edge_pos = ( edge_closest_pt + (cap_closest_pt + edge_axis * cap.size[0]) ) * 0.5 - edge_penetration = cap.size[0] - edge_dist - # prefer face contact if the edge axis is parallel to the face normal edge_dir_parallel_to_face = ( - jp.abs(edge_dir.dot(normal)) > 0.99 + jp.abs(edge_axis.dot(normal)) > 0.99 ) & ~degenerate_edge_dir + min_face_penetration = face_penetration.min() has_edge_contact = ( (edge_penetration > 0) + # prefer edge contact if the edge is smaller than face penetration + & jp.where( + min_face_penetration > 0, + edge_penetration < min_face_penetration, + True, + ) + # prefer face contact if the edge axis is parallel to the face normal & ~edge_dir_parallel_to_face - & ~outside_edge_voronoi + # make sure we have a shallow contact + & edge_voronoi_front ) # Get the contact info. @@ -367,7 +387,7 @@ def capsule_convex(cap: GeomInfo, convex: GeomInfo) -> Contact: n = n @ convex.mat.T dist = -jp.where( - has_edge_contact, penetration.at[0].set(edge_penetration), penetration + has_edge_contact, jp.array([edge_penetration, -1]), face_penetration ) frame = jax.vmap(math.make_frame)(n) return dist, pos, frame diff --git a/mjx/mujoco/mjx/_src/collision_driver_test.py b/mjx/mujoco/mjx/_src/collision_driver_test.py index 858e8795..0093f7f3 100644 --- a/mjx/mujoco/mjx/_src/collision_driver_test.py +++ b/mjx/mujoco/mjx/_src/collision_driver_test.py @@ -132,37 +132,70 @@ class SphereCollisionTest(parameterized.TestCase): """ - def test_sphere_convex(self): - d, dx = _collide(self._SPHERE_CONVEX) + def test_sphere_convex_face(self): + # no contact + xml = self._SPHERE_CONVEX.replace( + '', '' + ) + d, dx = _collide(xml) + self.assertEmpty(d.contact.dist) + self.assertGreater(dx.contact.dist, 0) + # face contact + xml = self._SPHERE_CONVEX.replace( + '', '' + ) + d, dx = _collide(xml) for field in dataclasses.fields(Contact): - _assert_attr_eq(dx.contact, d.contact, field.name, 'sphere_convex', 1e-4) + _assert_attr_eq(dx.contact, d.contact, field.name, 'face', 1e-4) - # test deep penetration + # deep face contact + xml = self._SPHERE_CONVEX.replace( + '', '' + ) + d, dx = _collide(xml) + self.assertTrue((dx.contact.dist < 0).all()) + self.assertTrue((d.contact.dist < 0).all()) + np.testing.assert_allclose(dx.contact.dist, [-0.07], atol=1e-5) + np.testing.assert_array_almost_equal(dx.contact.pos, d.contact.pos) + np.testing.assert_array_almost_equal( + dx.contact.frame, d.contact.frame.reshape((-1, 3, 3)) + ) + + def test_sphere_convex_edge(self): + # edge contact + d, dx = _collide(self._SPHERE_CONVEX) + for field in dataclasses.fields(Contact): + _assert_attr_eq(dx.contact, d.contact, field.name, 'edge', 1e-4) + + # deep edge penetration xml = self._SPHERE_CONVEX.replace( '', '' ) d, dx = _collide(xml) - self.assertTrue((dx.contact.dist < 0).all()) self.assertTrue((d.contact.dist < 0).all()) + np.testing.assert_allclose(dx.contact.dist, [-0.06], atol=1e-5) np.testing.assert_array_almost_equal(dx.contact.pos, d.contact.pos) np.testing.assert_array_almost_equal( dx.contact.frame, d.contact.frame.reshape((-1, 3, 3)) ) - # test sphere center on vertex + # vertex contact + xml = self._SPHERE_CONVEX.replace( + '', '' + ) + d, dx = _collide(xml) + for field in dataclasses.fields(Contact): + _assert_attr_eq(dx.contact, d.contact, field.name, 'vertex', 1e-4) + + # sphere center on vertex xml = self._SPHERE_CONVEX.replace( '', '' ) d, dx = _collide(xml) - - self.assertTrue((dx.contact.dist < 0).all()) - self.assertTrue((d.contact.dist < 0).all()) - np.testing.assert_array_almost_equal(dx.contact.pos, d.contact.pos) - np.testing.assert_array_almost_equal( - dx.contact.frame, d.contact.frame.reshape((-1, 3, 3)) - ) + for field in dataclasses.fields(Contact): + _assert_attr_eq(dx.contact, d.contact, field.name, 'vertex_center', 1e-4) class CapsuleCollisionTest(parameterized.TestCase): @@ -309,16 +342,17 @@ class CapsuleCollisionTest(parameterized.TestCase): def test_capsule_convex_edge_deep(self): """Tests deep edge penetration.""" xml = self._CAP_EDGE_BOX.replace( - ' Date: Thu, 21 Mar 2024 06:34:40 -0700 Subject: [PATCH 27/51] Allow meshes with flipped faces if `exactmeshinertia` is false. Fixes #1529. PiperOrigin-RevId: 617824308 Change-Id: I926c385475dd79f07e88fe1925ecbb2adb4f8917 --- src/user/user_mesh.cc | 2 +- test/user/user_mesh_test.cc | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/user/user_mesh.cc b/src/user/user_mesh.cc index c85e3cd9..db09b8fb 100644 --- a/src/user/user_mesh.cc +++ b/src/user/user_mesh.cc @@ -1637,7 +1637,7 @@ void mjCMesh::CheckMesh(mjtGeomInertia type) { if (!processed_) { return; } - if (invalidorientation_.first>=0 || invalidorientation_.second>=0) + if ((invalidorientation_.first>=0 || invalidorientation_.second>=0) && model->exactmeshinertia) throw mjCError(this, "faces of mesh '%s' have inconsistent orientation. Please check the " "faces containing the vertices %d and %d.", diff --git a/test/user/user_mesh_test.cc b/test/user/user_mesh_test.cc index 845dbba6..1eaaa0e1 100644 --- a/test/user/user_mesh_test.cc +++ b/test/user/user_mesh_test.cc @@ -464,19 +464,19 @@ TEST_F(MjCMeshTest, TinyInertiaFails) { "mass and inertia of moving bodies must be larger than mjMINVAL")); } -TEST_F(MjCMeshTest, MalformedFaceFails) { +TEST_F(MjCMeshTest, FlippedFaceAllowedInexactInertia) { const std::string xml_path = GetTestDataFilePath(kMalformedFaceOBJPath); std::array error; mjModel* model = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size()); - EXPECT_THAT(model, testing::IsNull()); - EXPECT_THAT(error.data(), HasSubstr( - "Error: faces of mesh 'malformed_face' have inconsistent orientation. " - "Please check the faces containing the vertices 1 and 2.")); + EXPECT_THAT(model, testing::NotNull()); + EXPECT_THAT(model->nmeshface, 4); + mj_deleteModel(model); } -TEST_F(MjCMeshTest, FlippedFaceFails) { +TEST_F(MjCMeshTest, FlippedFaceFailsExactInertia) { static constexpr char xml[] = R"( + Date: Thu, 21 Mar 2024 08:20:50 -0700 Subject: [PATCH 28/51] Do not attach elements not referenced in the subtree. PiperOrigin-RevId: 617849280 Change-Id: I391fe7c00f67d020d7394ddd31219d727b2eaa94 --- src/user/user_mesh.cc | 61 ++++-- src/user/user_model.cc | 175 ++++++++--------- src/user/user_model.h | 32 +++- src/user/user_objects.cc | 372 ++++++++++++++++++++++++++----------- src/user/user_objects.h | 37 +++- test/user/user_api_test.cc | 38 +++- 6 files changed, 475 insertions(+), 240 deletions(-) diff --git a/src/user/user_mesh.cc b/src/user/user_mesh.cc index db09b8fb..c6c5d9de 100644 --- a/src/user/user_mesh.cc +++ b/src/user/user_mesh.cc @@ -2120,6 +2120,14 @@ void mjCSkin::PointToLocal() { +void mjCSkin::NameSpace(const mjCModel* m) { + for (int i=0; i<(int)spec_bodyname_.size(); i++) { + spec_bodyname_[i] = m->prefix + spec_bodyname_[i] + m->suffix; + } +} + + + void mjCSkin::CopyFromSpec() { *static_cast(this) = spec; file_ = spec_file_; @@ -2163,6 +2171,20 @@ mjCSkin::~mjCSkin() { +void mjCSkin::ResolveReferences(const mjCModel* m) { + size_t nbone = bodyname_.size(); + bodyid.resize(nbone); + for (int i=0; iFindObject(mjOBJ_BODY, bodyname_[i]); + if (!pbody) { + throw mjCError(this, "unknown body '%s' in skin", bodyname_[i].c_str()); + } + bodyid[i] = pbody->id; + } +} + + + // compiler void mjCSkin::Compile(const mjVFS* vfs) { CopyFromSpec(); @@ -2243,14 +2265,7 @@ void mjCSkin::Compile(const mjVFS* vfs) { } // resolve body names - bodyid.resize(nbone); - for (int i=0; iFindObject(mjOBJ_BODY, bodyname_[i]); - if (!pbody) { - throw mjCError(this, "unknown body '%s' in skin", bodyname_[i].c_str()); - } - bodyid[i] = pbody->id; - } + ResolveReferences(model); // resolve material name mjCBase* pmat = model->FindObject(mjOBJ_MATERIAL, material_); @@ -2510,6 +2525,15 @@ void mjCFlex::PointToLocal() { } + +void mjCFlex::NameSpace(const mjCModel* m) { + for (int i=0; i<(int)spec_vertbody_.size(); i++) { + spec_vertbody_[i] = m->prefix + spec_vertbody_[i] + m->suffix; + } +} + + + void mjCFlex::CopyFromSpec() { *static_cast(this) = spec; spec.info = (mjString)&info; @@ -2542,6 +2566,18 @@ void mjCFlex::DelTexcoord() { } +void mjCFlex::ResolveReferences(const mjCModel* m) { + for (int i=0; i<(int)vertbody_.size(); i++) { + mjCBase* pbody = m->FindObject(mjOBJ_BODY, vertbody_[i]); + if (pbody) { + vertbodyid.push_back(pbody->id); + } else { + throw mjCError(this, "unkown body '%s' in flex", vertbody_[i].c_str()); + } + } +} + + // compiler void mjCFlex::Compile(const mjVFS* vfs) { CopyFromSpec(); @@ -2603,14 +2639,7 @@ void mjCFlex::Compile(const mjVFS* vfs) { } // resolve body ids - for (int i=0; i<(int)vertbody_.size(); i++) { - mjCBase* pbody = model->FindObject(mjOBJ_BODY, vertbody_[i]); - if (pbody) { - vertbodyid.push_back(pbody->id); - } else { - throw mjCError(this, "unkown body '%s' in flex", vertbody_[i].c_str()); - } - } + ResolveReferences(model); // process elements for (int e=0; e<(int)elem_.size()/(dim+1); e++) { diff --git a/src/user/user_model.cc b/src/user/user_model.cc index 8728b5e6..0cd073f6 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -120,6 +120,8 @@ mjCModel::mjCModel() { tuples.clear(); keys.clear(); defaults.clear(); + prefix = ""; + suffix = ""; Clear(); //------------------------ master default set @@ -180,101 +182,66 @@ mjCModel& mjCModel::operator=(const mjCModel& other) { +// copy vector of elements from another model to this model +template +void mjCModel::CopyList(std::vector& dest, + const std::vector& source, + std::map& def_map, + const std::vector& defaults) { + // loop over the elements from the other model + for (T* element : source) { + try { + // try to find the referenced object in this model + element->NameSpace(element->model); + element->CopyFromSpec(); + element->ResolveReferences(this); + } catch (mjCError err) { + // if not present, skip the element + continue; + } + // copy the element from the other model to this model + dest.push_back(new T(*element)); + dest.back()->model = this; + dest.back()->def = defaults[def_map[element->def]]; + } +} + + + mjCModel& mjCModel::operator+=(const mjCModel& other) { if (this != &other) { + // create global lists + MakeLists(bodies[0]); + CreateObjectLists(); + ProcessLists(); + + // copy all elements not in the tree std::map def_map; for (int i = 0; i < other.defaults.size(); i++) { defaults.push_back(new mjCDef(*other.defaults[i])); def_map[other.defaults[i]] = i; } - for (const mjCFlex* flex : other.flexes) { - flexes.push_back(new mjCFlex(*flex)); - flexes.back()->model = this; - flexes.back()->def = defaults[def_map[flex->def]]; - } - for (const mjCMesh* mesh : other.meshes) { - meshes.push_back(new mjCMesh(*mesh)); - meshes.back()->model = this; - meshes.back()->def = defaults[def_map[mesh->def]]; - } - for (const mjCSkin* skin : other.skins) { - skins.push_back(new mjCSkin(*skin)); - skins.back()->model = this; - skins.back()->def = defaults[def_map[skin->def]]; - } - for (const mjCHField* hfield : other.hfields) { - hfields.push_back(new mjCHField(*hfield)); - hfields.back()->model = this; - hfields.back()->def = defaults[def_map[hfield->def]]; - } - for (const mjCTexture* texture : other.textures) { - textures.push_back(new mjCTexture(*texture)); - textures.back()->model = this; - textures.back()->def = defaults[def_map[texture->def]]; - } - for (const mjCMaterial* material : other.materials) { - materials.push_back(new mjCMaterial(*material)); - materials.back()->model = this; - materials.back()->def = defaults[def_map[material->def]]; - } - for (const mjCPair* pair : other.pairs) { - pairs.push_back(new mjCPair(*pair)); - pairs.back()->model = this; - pairs.back()->def = defaults[def_map[pair->def]]; - } - for (const mjCBodyPair* exclude : other.excludes) { - excludes.push_back(new mjCBodyPair(*exclude)); - excludes.back()->model = this; - excludes.back()->def = defaults[def_map[exclude->def]]; - } - for (const mjCEquality* equality : other.equalities) { - equalities.push_back(new mjCEquality(*equality)); - equalities.back()->model = this; - equalities.back()->def = defaults[def_map[equality->def]]; - } - for (const mjCTendon* tendon : other.tendons) { - tendons.push_back(new mjCTendon(*tendon)); - tendons.back()->SetModel(this); - tendons.back()->def = defaults[def_map[tendon->def]]; - } - for (const mjCActuator* actuator : other.actuators) { - actuators.push_back(new mjCActuator(*actuator)); - actuators.back()->model = this; - actuators.back()->def = defaults[def_map[actuator->def]]; - } - for (const mjCSensor* sensor : other.sensors) { - sensors.push_back(new mjCSensor(*sensor)); - sensors.back()->model = this; - sensors.back()->def = defaults[def_map[sensor->def]]; - } - for (const mjCNumeric* numeric : other.numerics) { - numerics.push_back(new mjCNumeric(*numeric)); - numerics.back()->model = this; - numerics.back()->def = defaults[def_map[numeric->def]]; - } - for (const mjCText* text : other.texts) { - texts.push_back(new mjCText(*text)); - texts.back()->model = this; - texts.back()->def = defaults[def_map[text->def]]; - } - for (const mjCTuple* tuple : other.tuples) { - tuples.push_back(new mjCTuple(*tuple)); - tuples.back()->model = this; - tuples.back()->def = defaults[def_map[tuple->def]]; - } - for (const mjCKey* key : other.keys) { - keys.push_back(new mjCKey(*key)); - keys.back()->model = this; - keys.back()->def = defaults[def_map[key->def]]; - } + CopyList(flexes, other.flexes, def_map, defaults); + CopyList(meshes, other.meshes, def_map, defaults); + CopyList(skins, other.skins, def_map, defaults); + CopyList(hfields, other.hfields, def_map, defaults); + CopyList(textures, other.textures, def_map, defaults); + CopyList(materials, other.materials, def_map, defaults); + CopyList(pairs, other.pairs, def_map, defaults); + CopyList(excludes, other.excludes, def_map, defaults); + CopyList(tendons, other.tendons, def_map, defaults); + CopyList(equalities, other.equalities, def_map, defaults); + CopyList(actuators, other.actuators, def_map, defaults); + CopyList(sensors, other.sensors, def_map, defaults); + CopyList(numerics, other.numerics, def_map, defaults); + CopyList(texts, other.texts, def_map, defaults); + CopyList(tuples, other.tuples, def_map, defaults); + CopyList(keys, other.keys, def_map, defaults); // plugins are global plugins = other.plugins; active_plugins = other.active_plugins; - // create global lists - MakeLists(bodies[0]); - // update defaults for the copied objects for (int i = 1; i < other.bodies.size(); i++) { bodies[i]->def = defaults[def_map[other.bodies[i]->def]]; @@ -296,7 +263,7 @@ mjCModel& mjCModel::operator+=(const mjCModel& other) { } // cast children to mjCBase - CreateObjectLists(); + // restore to the same state as other if (!compiled) { @@ -670,28 +637,28 @@ mjCBase* mjCModel::GetObject(mjtObj type, int id) { //------------------------ API FOR ACCESS TO PRIVATE VARIABLES ------------------------------------- // compiled flag -bool mjCModel::IsCompiled(void) { +bool mjCModel::IsCompiled(void) const { return compiled; } // get reference of error object -const mjCError& mjCModel::GetError(void) { +const mjCError& mjCModel::GetError(void) const { return errInfo; } // pointer to world body -mjCBody* mjCModel::GetWorld(void) { +mjCBody* mjCModel::GetWorld(void) const { return bodies[0]; } // find default class name in array -mjCDef* mjCModel::FindDef(string name) { +mjCDef* mjCModel::FindDef(string name) const { for (int i=0; i<(int)defaults.size(); i++) { if (defaults[i]->name==name) { return defaults[i]; @@ -754,7 +721,7 @@ static T* findobject(std::string_view name, const vector& list, const mjKeyM } // find object in global lists given string type and name -mjCBase* mjCModel::FindObject(mjtObj type, string name) { +mjCBase* mjCModel::FindObject(mjtObj type, string name) const { if (!object_lists[type]) { return nullptr; } @@ -764,7 +731,7 @@ mjCBase* mjCModel::FindObject(mjtObj type, string name) { // find body by name -mjCBody* mjCModel::FindBody(mjCBody* body, std::string name) { +mjCBody* mjCModel::FindBody(mjCBody* body, std::string name) const { if (body->name == name) { return body; } @@ -782,7 +749,7 @@ mjCBody* mjCModel::FindBody(mjCBody* body, std::string name) { // find frame by name -mjCFrame* mjCModel::FindFrame(mjCBody* body, std::string name) { +mjCFrame* mjCModel::FindFrame(mjCBody* body, std::string name) const{ for (auto frame : body->frames) { if (frame->name == name) { return frame; @@ -802,7 +769,7 @@ mjCFrame* mjCModel::FindFrame(mjCBody* body, std::string name) { // detect null pose -bool mjCModel::IsNullPose(const mjtNum* pos, const mjtNum* quat) { +bool mjCModel::IsNullPose(const mjtNum* pos, const mjtNum* quat) const { bool result = true; // check position if given @@ -2913,6 +2880,21 @@ static void processlist(mjListKeyMap& ids, vector& list, } + +// set object ids, check for repeated names +void mjCModel::ProcessLists() { + for (int i = 0; i < mjNOBJECT; i++) { + if (i != mjOBJ_XBODY && object_lists[i]) { + processlist(ids, *object_lists[i], (mjtObj) i); + } + } + + // check repeated names in meta elements + processlist(ids, frames, mjOBJ_FRAME); +} + + + // error handler for low-level engine static thread_local std::jmp_buf error_jmp_buf; static thread_local char errortext[500] = ""; @@ -3046,14 +3028,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) { CheckEmptyNames(); // set object ids, check for repeated names - for (int i = 0; i < mjNOBJECT; i++) { - if (i != mjOBJ_XBODY && object_lists[i]) { - processlist(ids, *object_lists[i], (mjtObj) i); - } - } - - // check repeated names in meta elements - processlist(ids, frames, mjOBJ_FRAME); + ProcessLists(); // delete visual assets if (discardvisual) { diff --git a/src/user/user_model.h b/src/user/user_model.h index d6c1933f..167d3840 100644 --- a/src/user/user_model.h +++ b/src/user/user_model.h @@ -34,6 +34,11 @@ typedef std::map > mjKeyMap; typedef std::array mjListKeyMap; class mjCModel_ { + public: + // attach namespaces + std::string prefix; + std::string suffix; + protected: bool compiled; // already compiled flag @@ -185,6 +190,12 @@ class mjCModel : public mjCModel_, private mjSpec { mjCKey* AddKey(); mjCPlugin* AddPlugin(); + // copy vector of elements to this model + template void CopyList(std::vector& dest, + const std::vector& source, + std::map& def_map, + const std::vector& defaults); + // delete elements marked as discard=true template void Delete(std::vector& elements, const std::vector& discard); @@ -197,15 +208,15 @@ class mjCModel : public mjCModel_, private mjSpec { mjCBase* GetObject(mjtObj type, int id); // pointer to specified object // API for access to other variables - bool IsCompiled(); // is model already compiled - const mjCError& GetError(void); // get reference of error object - mjCBody* GetWorld(); // pointer to world body - mjCDef* FindDef(std::string name); // find default class name - mjCDef* AddDef(std::string name, int parentid); // add default class to array - mjCBase* FindObject(mjtObj type, std::string name); // find object given type and name - mjCBody* FindBody(mjCBody* body, std::string name); // find body given name - mjCFrame* FindFrame(mjCBody* body, std::string name); // find frame given name - bool IsNullPose(const mjtNum* pos, const mjtNum* quat); // detect null pose + bool IsCompiled() const; // is model already compiled + const mjCError& GetError(void) const; // get reference of error object + mjCBody* GetWorld() const; // pointer to world body + mjCDef* FindDef(std::string name) const; // find default class name + mjCDef* AddDef(std::string name, int parentid); // add default class to array + mjCBase* FindObject(mjtObj type, std::string name) const; // find object given type and name + mjCBody* FindBody(mjCBody* body, std::string name) const; // find body given name + mjCFrame* FindFrame(mjCBody* body, std::string name) const; // find frame given name + bool IsNullPose(const mjtNum* pos, const mjtNum* quat) const; // detect null pose // accessors std::string get_meshdir(void) const { return meshdir_; } @@ -289,6 +300,9 @@ class mjCModel : public mjCModel_, private mjSpec { // create mjCBase lists from children lists void CreateObjectLists(); + // populate objects ids + void ProcessLists(); + mjListKeyMap ids; // map from object names to ids mjCError errInfo; // last error info bool plugin_owner; // this class allocated the plugins diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index e4f3c744..8e2a1d78 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -793,15 +793,45 @@ mjCBody::~mjCBody() { // apply prefix and suffix, propagate to children -void mjCBody::SetNameSpace() { +void mjCBody::NameSpace(const mjCModel* m) { if (!name.empty()) { name = prefix + name + suffix; } + for (auto& joint : joints) { + if (!joint->name.empty()) { + joint->name = prefix + joint->name + suffix; + } + } + + for (auto& geom : geoms) { + if (!geom->name.empty()) { + geom->name = prefix + geom->name + suffix; + } + } + + for (auto& site : sites) { + if (!site->name.empty()) { + site->name = prefix + site->name + suffix; + } + } + + for (auto& camera : cameras) { + if (!camera->name.empty()) { + camera->name = prefix + camera->name + suffix; + } + } + + for (auto& light : lights) { + if (!light->name.empty()) { + light->name = prefix + light->name + suffix; + } + } + for (auto& body : bodies) { - body->prefix = prefix; - body->suffix = suffix; - body->SetNameSpace(); + body->prefix = m->prefix; + body->suffix = m->suffix; + body->NameSpace(m); } } @@ -1368,8 +1398,10 @@ mjCFrame& mjCFrame::operator=(const mjCFrame& other) { // attach body to frame mjCFrame& mjCFrame::operator+=(const mjCBody& other) { mjCBody* subtree = new mjCBody(other, model); + other.model->prefix = subtree->prefix; + other.model->suffix = subtree->suffix; subtree->SetFrame(this); - subtree->SetNameSpace(); + subtree->NameSpace(other.model); // add to tree *body += *subtree; @@ -3777,8 +3809,8 @@ mjCPair& mjCPair::operator=(const mjCPair& other) { this->spec = other.spec; *static_cast(this) = static_cast(other); *static_cast(this) = static_cast(other); - this->geom1 = other.geom1; - this->geom2 = other.geom2; + this->geom1 = nullptr; + this->geom2 = nullptr; } PointToLocal(); return *this; @@ -3797,6 +3829,16 @@ void mjCPair::PointToLocal() { +void mjCPair::NameSpace(const mjCModel* m) { + if (!name.empty()) { + name = m->prefix + name + m->suffix; + } + spec_geomname1_ = m->prefix + spec_geomname1_ + m->suffix; + spec_geomname2_ = m->prefix + spec_geomname2_ + m->suffix; +} + + + void mjCPair::CopyFromSpec() { *static_cast(this) = spec; geomname1_ = spec_geomname1_; @@ -3807,31 +3849,19 @@ void mjCPair::CopyFromSpec() { -// compiler -void mjCPair::Compile(void) { - CopyFromSpec(); - - // check condim - if (condim!=1 && condim!=3 && condim!=4 && condim!=6) { - throw mjCError(this, "invalid condim in collision %d", "", id); - } - +void mjCPair::ResolveReferences(const mjCModel* m) { // find geom 1 - geom1 = (mjCGeom*)model->FindObject(mjOBJ_GEOM, geomname1_); + geom1 = (mjCGeom*)m->FindObject(mjOBJ_GEOM, geomname1_); if (!geom1) { throw mjCError(this, "geom '%s' not found in collision %d", geomname1_.c_str(), id); } // find geom 2 - geom2 = (mjCGeom*)model->FindObject(mjOBJ_GEOM, geomname2_); + geom2 = (mjCGeom*)m->FindObject(mjOBJ_GEOM, geomname2_); if (!geom2) { throw mjCError(this, "geom '%s' not found in collision %d", geomname2_.c_str(), id); } - // mark geoms as not visual - geom1->SetNotVisual(); - geom2->SetNotVisual(); - // swap if body1 > body2 if (geom1->body->id > geom2->body->id) { string nametmp = geomname1_; @@ -3845,6 +3875,25 @@ void mjCPair::Compile(void) { // get geom ids and body signature signature = ((geom1->body->id)<<16) + geom2->body->id; +} + + + +// compiler +void mjCPair::Compile(void) { + CopyFromSpec(); + + // check condim + if (condim!=1 && condim!=3 && condim!=4 && condim!=6) { + throw mjCError(this, "invalid condim in collision %d", "", id); + } + + // find geoms + ResolveReferences(model); + + // mark geoms as not visual + geom1->SetNotVisual(); + geom2->SetNotVisual(); // set undefined margin: max if (!mjuu_defined(margin)) { @@ -3989,6 +4038,16 @@ void mjCBodyPair::PointToLocal() { +void mjCBodyPair::NameSpace(const mjCModel* m) { + if (!name.empty()) { + name = m->prefix + name + m->suffix; + } + spec_bodyname1_ = m->prefix + spec_bodyname1_ + m->suffix; + spec_bodyname2_ = m->prefix + spec_bodyname2_ + m->suffix; +} + + + void mjCBodyPair::CopyFromSpec() { *static_cast(this) = spec; bodyname1_ = spec_bodyname1_; @@ -3999,18 +4058,15 @@ void mjCBodyPair::CopyFromSpec() { -// compiler -void mjCBodyPair::Compile(void) { - CopyFromSpec(); - +void mjCBodyPair::ResolveReferences(const mjCModel* m) { // find body 1 - mjCBody* pb1 = (mjCBody*)model->FindObject(mjOBJ_BODY, bodyname1_); + mjCBody* pb1 = (mjCBody*)m->FindObject(mjOBJ_BODY, bodyname1_); if (!pb1) { throw mjCError(this, "body '%s' not found in bodypair %d", bodyname1_.c_str(), id); } // find body 2 - mjCBody* pb2 = (mjCBody*)model->FindObject(mjOBJ_BODY, bodyname2_); + mjCBody* pb2 = (mjCBody*)m->FindObject(mjOBJ_BODY, bodyname2_); if (!pb2) { throw mjCError(this, "body '%s' not found in bodypair %d", bodyname2_.c_str(), id); } @@ -4034,6 +4090,16 @@ void mjCBodyPair::Compile(void) { +// compiler +void mjCBodyPair::Compile(void) { + CopyFromSpec(); + + // find bodies + ResolveReferences(model); +} + + + //------------------ class mjCEquality implementation ---------------------------------------------- // initialize default constraint @@ -4091,6 +4157,17 @@ void mjCEquality::PointToLocal() { } + +void mjCEquality::NameSpace(const mjCModel* m) { + if (!name.empty()) { + name = m->prefix + name + m->suffix; + } + spec_name1_ = m->prefix + spec_name1_ + m->suffix; + spec_name2_ = m->prefix + spec_name2_ + m->suffix; +} + + + void mjCEquality::CopyFromSpec() { *static_cast(this) = spec; name1_ = spec_name1_; @@ -4100,10 +4177,8 @@ void mjCEquality::CopyFromSpec() { } -// compiler -void mjCEquality::Compile(void) { - CopyFromSpec(); +void mjCEquality::ResolveReferences(const mjCModel* m) { mjtObj objtype; mjCBase *px1, *px2; mjtJoint jt1, jt2; @@ -4122,7 +4197,7 @@ void mjCEquality::Compile(void) { } // find object 1, get id - px1 = model->FindObject(objtype, name1_); + px1 = m->FindObject(objtype, name1_); if (!px1) { throw mjCError(this, "unknown element '%s' in equality constraint %d", name1_.c_str(), id); } @@ -4130,7 +4205,7 @@ void mjCEquality::Compile(void) { // find object 2, get id if (!name2_.empty()) { - px2 = model->FindObject(objtype, name2_); + px2 = m->FindObject(objtype, name2_); if (!px2) { throw mjCError(this, "unknown element '%s' in equality constraint %d", name2_.c_str(), id); } @@ -4153,11 +4228,6 @@ void mjCEquality::Compile(void) { obj2id = 0; } - // make sure flex is not rigid - if (type==mjEQ_FLEX && model->flexes[obj1id]->rigid) { - throw mjCError(this, "rigid flex '%s' in equality constraint %d", name1_.c_str(), id); - } - // make sure the two objects are different if (obj1id==obj2id) { throw mjCError(this, "element '%s' is repeated in equality constraint %d", name1_.c_str(), id); @@ -4177,6 +4247,21 @@ void mjCEquality::Compile(void) { +// compiler +void mjCEquality::Compile(void) { + CopyFromSpec(); + + // find objects + ResolveReferences(model); + + // make sure flex is not rigid + if (type==mjEQ_FLEX && model->flexes[obj1id]->rigid) { + throw mjCError(this, "rigid flex '%s' in equality constraint %d", name1_.c_str(), id); + } +} + + + //------------------ class mjCTendon implementation ------------------------------------------------ // constructor @@ -4243,6 +4328,17 @@ void mjCTendon::PointToLocal() { +void mjCTendon::NameSpace(const mjCModel* m) { + if (!name.empty()) { + name = m->prefix + name + m->suffix; + } + for (int i=0; iNameSpace(model); + } +} + + + void mjCTendon::CopyFromSpec() { *static_cast(this) = spec; material_ = spec_material_; @@ -4361,6 +4457,14 @@ mjCWrap* mjCTendon::GetWrap(int id) { +void mjCTendon::ResolveReferences(const mjCModel* m) { + for (int i=0; iResolveReferences(m); + } +} + + + // compiler void mjCTendon::Compile(void) { CopyFromSpec(); @@ -4395,9 +4499,7 @@ void mjCTendon::Compile(void) { } // compile objects in path - for (int i=0; iCompile(); - } + ResolveReferences(model); // check path for (int i=0; iprefix + name + m->suffix; + sidesite = m->prefix + sidesite + m->suffix; +} + + + +void mjCWrap::ResolveReferences(const mjCModel* m) { mjCBase *pside; // handle wrap object types switch (type) { case mjWRAP_JOINT: // joint // find joint by name - obj = model->FindObject(mjOBJ_JOINT, name); + obj = m->FindObject(mjOBJ_JOINT, name); if (!obj) { throw mjCError(this, "joint '%s' not found in tendon %d, wrap %d", @@ -4555,7 +4663,7 @@ void mjCWrap::Compile(void) { case mjWRAP_SPHERE: // geom (cylinder type set here) // find geom by name - obj = model->FindObject(mjOBJ_GEOM, name); + obj = m->FindObject(mjOBJ_GEOM, name); if (!obj) { throw mjCError(this, "geom '%s' not found in tendon %d, wrap %d", @@ -4574,7 +4682,7 @@ void mjCWrap::Compile(void) { // process side site if (!sidesite.empty()) { // find site by name - pside = model->FindObject(mjOBJ_SITE, sidesite); + pside = m->FindObject(mjOBJ_SITE, sidesite); if (!pside) { throw mjCError(this, "side site '%s' not found in tendon %d, wrap %d", @@ -4598,7 +4706,7 @@ void mjCWrap::Compile(void) { case mjWRAP_SITE: // site // find site by name - obj = model->FindObject(mjOBJ_SITE, name); + obj = m->FindObject(mjOBJ_SITE, name); if (!obj) { throw mjCError(this, "site '%s' not found in wrap %d", name.c_str(), id); } @@ -4618,6 +4726,7 @@ mjCActuator::mjCActuator(mjCModel* _model, mjCDef* _def) { mjm_defaultActuator(spec); // clear private variables + ptarget = nullptr; spec_target_.clear(); spec_slidersite_.clear(); spec_refsite_.clear(); @@ -4653,6 +4762,7 @@ mjCActuator& mjCActuator::operator=(const mjCActuator& other) { this->spec = other.spec; *static_cast(this) = static_cast(other); *static_cast(this) = static_cast(other); + ptarget = nullptr; } PointToLocal(); return *this; @@ -4681,6 +4791,17 @@ void mjCActuator::PointToLocal() { +void mjCActuator::NameSpace(const mjCModel* m) { + if (!name.empty()) { + name = m->prefix + name + m->suffix; + } + spec_target_ = m->prefix + spec_target_ + m->suffix; + spec_refsite_ = m->prefix + spec_refsite_ + m->suffix; + spec_slidersite_ = m->prefix + spec_slidersite_ + m->suffix; +} + + + void mjCActuator::CopyFromSpec() { *static_cast(this) = spec; userdata_ = spec_userdata_; @@ -4699,31 +4820,13 @@ void mjCActuator::CopyFromSpec() { -// compiler -void mjCActuator::Compile(void) { - CopyFromSpec(); +void mjCActuator::ResolveReferences(const mjCModel* m) { mjCJoint* pjnt; - - // resize userdata - if (userdata_.size() > model->nuser_actuator) { - throw mjCError(this, "user has more values than nuser_actuator in actuator '%s' (id = %d)", - name.c_str(), id); - } - userdata_.resize(model->nuser_actuator); - - // check for missing target name - if (target_.empty()) { - throw mjCError(this, - "missing transmission target for actuator '%s' (id = %d)", name.c_str(), id); - } - - // find transmission target in object arrays - mjCBase* ptarget = 0; switch (trntype) { case mjTRN_JOINT: case mjTRN_JOINTINPARENT: // get joint - ptarget = model->FindObject(mjOBJ_JOINT, target_); + ptarget = m->FindObject(mjOBJ_JOINT, target_); if (!ptarget) { throw mjCError(this, "unknown transmission target '%s' for actuator id = %d", target_.c_str(), id); @@ -4743,7 +4846,7 @@ void mjCActuator::Compile(void) { if (slidersite_.empty()) { throw mjCError(this, "missing base site for slider-crank '%s' (id = %d)", name.c_str(), id); } - ptarget = model->FindObject(mjOBJ_SITE, slidersite_); + ptarget = m->FindObject(mjOBJ_SITE, slidersite_); if (!ptarget) { throw mjCError(this, "base site '%s' not found for actuator %d", slidersite_.c_str(), id); } @@ -4756,18 +4859,18 @@ void mjCActuator::Compile(void) { } // proceed with regular target - ptarget = model->FindObject(mjOBJ_SITE, target_); + ptarget = m->FindObject(mjOBJ_SITE, target_); break; case mjTRN_TENDON: // get tendon - ptarget = model->FindObject(mjOBJ_TENDON, target_); + ptarget = m->FindObject(mjOBJ_TENDON, target_); break; case mjTRN_SITE: // get refsite, copy into trnid[1] if (!refsite_.empty()) { - ptarget = model->FindObject(mjOBJ_SITE, refsite_); + ptarget = m->FindObject(mjOBJ_SITE, refsite_); if (!ptarget) { throw mjCError(this, "reference site '%s' not found for actuator %d", refsite_.c_str(), id); } @@ -4775,12 +4878,12 @@ void mjCActuator::Compile(void) { } // proceed with regular site target - ptarget = model->FindObject(mjOBJ_SITE, target_); + ptarget = m->FindObject(mjOBJ_SITE, target_); break; case mjTRN_BODY: // get body - ptarget = model->FindObject(mjOBJ_BODY, target_); + ptarget = m->FindObject(mjOBJ_BODY, target_); break; default: @@ -4793,6 +4896,29 @@ void mjCActuator::Compile(void) { } else { trnid[0] = ptarget->id; } +} + + + +// compiler +void mjCActuator::Compile(void) { + CopyFromSpec(); + + // resize userdata + if (userdata_.size() > model->nuser_actuator) { + throw mjCError(this, "user has more values than nuser_actuator in actuator '%s' (id = %d)", + name.c_str(), id); + } + userdata_.resize(model->nuser_actuator); + + // check for missing target name + if (target_.empty()) { + throw mjCError(this, + "missing transmission target for actuator '%s' (id = %d)", name.c_str(), id); + } + + // find transmission target in object arrays + ResolveReferences(model); // handle inheritrange if (gaintype == mjGAIN_FIXED && biastype == mjBIAS_AFFINE && @@ -4812,7 +4938,7 @@ void mjCActuator::Compile(void) { const double* target_range; if (trntype == mjTRN_JOINT) { - pjnt = (mjCJoint*) ptarget; + mjCJoint* pjnt = (mjCJoint*) ptarget; if (pjnt->spec.type != mjJNT_HINGE && pjnt->spec.type != mjJNT_SLIDE) { throw mjCError(this, "inheritrange can only be used with hinge and slide joints, " "actuator '%s' (id = %d)", name.c_str(), id); @@ -4950,6 +5076,7 @@ mjCSensor::mjCSensor(mjCModel* _model) { spec_refname_.clear(); spec_userdata_.clear(); obj = nullptr; + ref = nullptr; refid = -1; // in case this sensor is not compiled @@ -4972,6 +5099,8 @@ mjCSensor& mjCSensor::operator=(const mjCSensor& other) { this->spec = other.spec; *static_cast(this) = static_cast(other); *static_cast(this) = static_cast(other); + obj = nullptr; + ref = nullptr; } PointToLocal(); return *this; @@ -4993,6 +5122,16 @@ void mjCSensor::PointToLocal() { +void mjCSensor::NameSpace(const mjCModel* m) { + if (!name.empty()) { + name = m->prefix + name + m->suffix; + } + spec_objname_ = m->prefix + spec_objname_ + m->suffix; + spec_refname_ = m->prefix + spec_refname_ + m->suffix; +} + + + void mjCSensor::CopyFromSpec() { *static_cast(this) = spec; userdata_ = spec_userdata_; @@ -5009,27 +5148,7 @@ void mjCSensor::CopyFromSpec() { -// compiler -void mjCSensor::Compile(void) { - CopyFromSpec(); - - // resize userdata - if (userdata_.size() > model->nuser_sensor) { - throw mjCError(this, "user has more values than nuser_sensor in sensor '%s' (id = %d)", - name.c_str(), id); - } - userdata_.resize(model->nuser_sensor); - - // require non-negative noise - if (noise<0) { - throw mjCError(this, "negative noise in sensor '%s' (id = %d)", name.c_str(), id); - } - - // require non-negative cutoff - if (cutoff<0) { - throw mjCError(this, "negative cutoff in sensor '%s' (id = %d)", name.c_str(), id); - } - +void mjCSensor::ResolveReferences(const mjCModel* m) { // get objid from objtype and objname if (objtype!=mjOBJ_UNKNOWN) { // check for missing object name @@ -5040,7 +5159,7 @@ void mjCSensor::Compile(void) { } // find name - obj = model->FindObject(objtype, objname_); + obj = m->FindObject(objtype, objname_); if (!obj) { throw mjCError(this, "unrecognized name of sensorized object in sensor '%s' (id = %d)", @@ -5067,8 +5186,8 @@ void mjCSensor::Compile(void) { } // find name - mjCBase* pref = model->FindObject(reftype, refname_); - if (!pref) { + ref = m->FindObject(reftype, refname_); + if (!ref) { throw mjCError(this, "unrecognized name of reference frame object in sensor '%s' (id = %d)", name.c_str(), id); @@ -5083,8 +5202,35 @@ void mjCSensor::Compile(void) { } // get sensorized object id - refid = pref->id; + refid = ref->id; } +} + + + +// compiler +void mjCSensor::Compile(void) { + CopyFromSpec(); + + // resize userdata + if (userdata_.size() > model->nuser_sensor) { + throw mjCError(this, "user has more values than nuser_sensor in sensor '%s' (id = %d)", + name.c_str(), id); + } + userdata_.resize(model->nuser_sensor); + + // require non-negative noise + if (noise<0) { + throw mjCError(this, "negative noise in sensor '%s' (id = %d)", name.c_str(), id); + } + + // require non-negative cutoff + if (cutoff<0) { + throw mjCError(this, "negative cutoff in sensor '%s' (id = %d)", name.c_str(), id); + } + + // Find referenced object + ResolveReferences(model); // process according to sensor type switch (type) { @@ -5126,7 +5272,7 @@ void mjCSensor::Compile(void) { // check for camera resolution for camera projection sensor if (type==mjSENS_CAMPROJECTION) { - mjCCamera* camref = (mjCCamera*) model->FindObject(mjOBJ_CAMERA, refname_); + mjCCamera* camref = (mjCCamera*)ref; if (!camref->resolution[0] || !camref->resolution[1]) { throw mjCError(this, "camera projection sensor requires camera resolution '%s' (id = %d)", @@ -5619,6 +5765,17 @@ void mjCTuple::PointToLocal() { +void mjCTuple::NameSpace(const mjCModel* m) { + if (!name.empty()) { + name = m->prefix + name + m->suffix; + } + for (int i=0; iprefix + spec_objname_[i] + m->suffix; + } +} + + + void mjCTuple::CopyFromSpec() { *static_cast(this) = spec; objtype_ = spec_objtype_; @@ -5644,10 +5801,7 @@ mjCTuple::~mjCTuple() { -// compiler -void mjCTuple::Compile(void) { - CopyFromSpec(); - +void mjCTuple::ResolveReferences(const mjCModel* m) { // check for empty tuple if (objtype_.empty()) { throw mjCError(this, "tuple '%s' (id = %d) is empty", name.c_str(), id); @@ -5665,7 +5819,7 @@ void mjCTuple::Compile(void) { // find objects, fill in ids for (int i=0; iFindObject(objtype_[i], objname_[i]); + mjCBase* res = m->FindObject(objtype_[i], objname_[i]); if (!res) { throw mjCError(this, "unrecognized object '%s' in tuple %d", objname_[i].c_str(), id); } @@ -5682,6 +5836,14 @@ void mjCTuple::Compile(void) { +// compiler +void mjCTuple::Compile(void) { + CopyFromSpec(); + ResolveReferences(model); +} + + + //------------------ class mjCKey implementation --------------------------------------------------- // constructor diff --git a/src/user/user_objects.h b/src/user/user_objects.h index 50ae9f2e..1a4cd0c6 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -198,6 +198,12 @@ class mjCBase : public mjCBase_ { // Copy spec into private attributes virtual void CopyFromSpec() {} + // Throws an error if any of the references is missing + virtual void ResolveReferences(const mjCModel* m) {} + + // Appends prefix and suffix to reference + virtual void NameSpace(const mjCModel* m) {} + // Copy assignment mjCBase& operator=(const mjCBase& other); @@ -284,7 +290,7 @@ class mjCBody : public mjCBody_, private mjmBody { mjCBase* FindObject(mjtObj type, std::string name, bool recursive = true); // Propagate suffix and prefix to the whole tree - void SetNameSpace(); + void NameSpace(const mjCModel* m); // set explicitinertial to true void MakeInertialExplicit(); @@ -682,6 +688,8 @@ class mjCFlex: public mjCFlex_, private mjmFlex { void CopyFromSpec(void); void PointToLocal(void); + void ResolveReferences(const mjCModel* m); + void NameSpace(const mjCModel* m); // used by mjXWriter and mjCModel const std::string& get_material() { return material_; } @@ -937,6 +945,8 @@ class mjCSkin: public mjCSkin_, private mjmSkin { mjCSkin& operator=(const mjCSkin& other); // copy assignment ~mjCSkin(); // destructor + void ResolveReferences(const mjCModel* m); + void NameSpace(const mjCModel* m); void Compile(const mjVFS* vfs); // compiler void LoadSKN(mjResource* resource); // load skin in SKN BIN format }; @@ -1115,6 +1125,8 @@ class mjCPair : public mjCPair_, private mjmPair { void CopyFromSpec(); void PointToLocal(); + void ResolveReferences(const mjCModel* m); + void NameSpace(const mjCModel* m); std::string get_geomname1() { return geomname1_; } std::string get_geomname2() { return geomname2_; } @@ -1162,6 +1174,8 @@ class mjCBodyPair : public mjCBodyPair_, private mjmExclude { void CopyFromSpec(); void PointToLocal(); + void ResolveReferences(const mjCModel* m); + void NameSpace(const mjCModel* m); std::string get_bodyname1() const { return bodyname1_; } std::string get_bodyname2() const { return bodyname2_; } @@ -1207,6 +1221,8 @@ class mjCEquality : public mjCEquality_, private mjmEquality { void CopyFromSpec(); void PointToLocal(); + void ResolveReferences(const mjCModel* m); + void NameSpace(const mjCModel* m); private: mjCEquality(mjCModel* = 0, mjCDef* = 0); // constructor @@ -1264,6 +1280,8 @@ class mjCTendon : public mjCTendon_, private mjmTendon { void CopyFromSpec(); void PointToLocal(); + void ResolveReferences(const mjCModel* m); + void NameSpace(const mjCModel* m); void SetModel(mjCModel* _model); bool is_limited() const; @@ -1299,6 +1317,9 @@ class mjCWrap : public mjCWrap_, private mjmWrap { using mjCBase::info; void PointToLocal(); + void ResolveReferences(const mjCModel* m); + void NameSpace(const mjCModel* m); + mjCBase* obj; // wrap object pointer private: @@ -1306,8 +1327,6 @@ class mjCWrap : public mjCWrap_, private mjmWrap { mjCWrap(const mjCWrap& other); // copy constructor mjCWrap& operator=(const mjCWrap& other); // copy assignment - void Compile(void); // compiler - mjCTendon* tendon; // tendon owning this wrap }; @@ -1393,6 +1412,10 @@ class mjCActuator : public mjCActuator_, private mjmActuator { void Compile(void); // compiler void CopyFromSpec(); void PointToLocal(); + void ResolveReferences(const mjCModel* m); + void NameSpace(const mjCModel* m); + + mjCBase* ptarget; // transmission target }; @@ -1403,7 +1426,6 @@ class mjCActuator : public mjCActuator_, private mjmActuator { class mjCSensor_ : public mjCBase { protected: int refid; // id of reference frame - mjCBase* obj; // sensorized object // variable-size data std::string plugin_name; @@ -1440,6 +1462,11 @@ class mjCSensor : public mjCSensor_, private mjmSensor { void Compile(void); // compiler void CopyFromSpec(); void PointToLocal(); + void ResolveReferences(const mjCModel* m); + void NameSpace(const mjCModel* m); + + mjCBase* obj; // sensorized object + mjCBase* ref; // sensorized reference }; @@ -1533,6 +1560,8 @@ class mjCTuple : public mjCTuple_, private mjmTuple { void PointToLocal(); void CopyFromSpec(); + void ResolveReferences(const mjCModel* m); + void NameSpace(const mjCModel* m); private: mjCTuple(mjCModel*); // constructor diff --git a/test/user/user_api_test.cc b/test/user/user_api_test.cc index d6aa0f87..e0a83d5f 100644 --- a/test/user/user_api_test.cc +++ b/test/user/user_api_test.cc @@ -215,13 +215,27 @@ TEST_F(MujocoTest, Attach) { static constexpr char xml_child[] = R"( - - + + + + + + + + + + + + + + + + )"; static constexpr char xml_result[] = R"( @@ -231,8 +245,8 @@ TEST_F(MujocoTest, Attach) { - - + + @@ -240,6 +254,18 @@ TEST_F(MujocoTest, Attach) { + + + + + + + + + + + + )"; // model with one free sphere and a frame @@ -255,7 +281,7 @@ TEST_F(MujocoTest, Attach) { EXPECT_THAT(child, NotNull()) << er.data(); // get subtree - mjmBody* body = mjm_findBody(child, "cylinder"); + mjmBody* body = mjm_findBody(child, "body"); EXPECT_THAT(body, NotNull()); // attach child to parent frame @@ -267,7 +293,7 @@ TEST_F(MujocoTest, Attach) { EXPECT_THAT(m_attached, NotNull()); // check full name stored in mjModel - EXPECT_STREQ(mj_id2name(m_attached, mjOBJ_BODY, 2), "attached-cylinder-1"); + EXPECT_STREQ(mj_id2name(m_attached, mjOBJ_BODY, 2), "attached-body-1"); // check body 2 is attached to body 1 EXPECT_THAT(m_attached->body_parentid[2], 1); From af38845280943d2caee90723d51709ce3bf4594d Mon Sep 17 00:00:00 2001 From: Levi Burner Date: Thu, 21 Mar 2024 12:47:56 -0400 Subject: [PATCH 29/51] [Python Viewer] clear load error on successful reload, fixes #1116 --- python/mujoco/viewer.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/python/mujoco/viewer.py b/python/mujoco/viewer.py index 107ee83f..7e01d1bd 100644 --- a/python/mujoco/viewer.py +++ b/python/mujoco/viewer.py @@ -199,6 +199,9 @@ def _reload( path = load_tuple[2] if len(load_tuple) == 3 else '' simulate.load(m, d, path) + # Make sure any load_error message is cleared + simulate.load_error = '' + if notify_loaded: notify_loaded() From 848e01402036b2070eeb36503815cac0cc87324c Mon Sep 17 00:00:00 2001 From: Levi Burner Date: Thu, 21 Mar 2024 11:39:37 -0700 Subject: [PATCH 30/51] Copybara import of the project: -- 40996ab1a05f328c2b5d1b940abb189d43f646de by Levi Burner : [Python Viewer] load mjb files, fixes #1421 COPYBARA_INTEGRATE_REVIEW=https://github.com/google-deepmind/mujoco/pull/1535 from aftersomemath:simulate-load-mjb 40996ab1a05f328c2b5d1b940abb189d43f646de PiperOrigin-RevId: 617913250 Change-Id: I09e858495784122c29e0a3895ce43b95010003bc --- python/mujoco/viewer.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python/mujoco/viewer.py b/python/mujoco/viewer.py index 107ee83f..1855935f 100644 --- a/python/mujoco/viewer.py +++ b/python/mujoco/viewer.py @@ -169,7 +169,10 @@ def _file_loader(path: str) -> _LoaderWithPathType: """Loads an MJCF model from file path.""" def load(path=path) -> Tuple[mujoco.MjModel, mujoco.MjData, str]: - m = mujoco.MjModel.from_xml_path(path) + if len(path) >= 4 and path[-4:] == '.mjb': + m = mujoco.MjModel.from_binary_path(path) + else: + m = mujoco.MjModel.from_xml_path(path) d = mujoco.MjData(m) return m, d, path From 4660a297d1bafe5b76a5f88af6aa485552c63258 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Thu, 21 Mar 2024 18:04:06 -0700 Subject: [PATCH 31/51] rename mjspec api structs and functions `mjm` -> `mjs` PiperOrigin-RevId: 618017976 Change-Id: I5f790167e5ca670f8d5f92e8e1c920db8d236144 --- src/user/user_api.cc | 128 +++++----- src/user/user_api.h | 324 ++++++++++++------------ src/user/user_composite.cc | 300 +++++++++++----------- src/user/user_composite.h | 32 +-- src/user/user_flexcomp.cc | 58 ++--- src/user/user_flexcomp.h | 4 +- src/user/user_init.cc | 94 +++---- src/user/user_mesh.cc | 18 +- src/user/user_model.cc | 2 +- src/user/user_objects.cc | 144 +++++------ src/user/user_objects.h | 102 ++++---- src/xml/xml.cc | 12 +- src/xml/xml_api.cc | 14 +- src/xml/xml_base.cc | 3 +- src/xml/xml_base.h | 2 +- src/xml/xml_native_reader.cc | 470 +++++++++++++++++------------------ src/xml/xml_native_reader.h | 36 +-- src/xml/xml_native_writer.cc | 28 +-- src/xml/xml_native_writer.h | 2 +- src/xml/xml_urdf.cc | 94 +++---- src/xml/xml_urdf.h | 4 +- test/user/user_api_test.cc | 48 ++-- 22 files changed, 960 insertions(+), 959 deletions(-) diff --git a/src/user/user_api.cc b/src/user/user_api.cc index 10ebc5d1..6af8b3d9 100644 --- a/src/user/user_api.cc +++ b/src/user/user_api.cc @@ -49,7 +49,7 @@ static T& operator+(T& base, std::string_view suffix) { // create model -mjSpec* mjm_createSpec() { +mjSpec* mjs_createSpec() { mjCModel* modelC = new mjCModel; return &modelC->spec; } @@ -57,7 +57,7 @@ mjSpec* mjm_createSpec() { // copy model -mjSpec* mjm_copySpec(const mjSpec* s) { +mjSpec* mjs_copySpec(const mjSpec* s) { mjCModel* modelC = new mjCModel(*reinterpret_cast(s->element)); return &modelC->spec; } @@ -65,7 +65,7 @@ mjSpec* mjm_copySpec(const mjSpec* s) { // copy back model -void mjm_copyBack(mjSpec* s, const mjModel* m) { +void mjs_copyBack(mjSpec* s, const mjModel* m) { mjCModel* modelC = reinterpret_cast(s->element); modelC->CopyBack(m); } @@ -73,7 +73,7 @@ void mjm_copyBack(mjSpec* s, const mjModel* m) { // compile model -mjModel* mjm_compile(mjSpec* s, const mjVFS* vfs) { +mjModel* mjs_compile(mjSpec* s, const mjVFS* vfs) { mjCModel* modelC = reinterpret_cast(s->element); return modelC->Compile(vfs); } @@ -81,7 +81,7 @@ mjModel* mjm_compile(mjSpec* s, const mjVFS* vfs) { // attach body to a frame of the parent -int mjm_attachBody(mjmFrame* parent, const mjmBody* child, +int mjs_attachBody(mjsFrame* parent, const mjsBody* child, const char* prefix, const char* suffix) { mjCFrame* frame_parent = reinterpret_cast(parent->element); mjCBody* child_body = reinterpret_cast(child->element); @@ -92,7 +92,7 @@ int mjm_attachBody(mjmFrame* parent, const mjmBody* child, // get error message from model -const char* mjm_getError(mjSpec* s) { +const char* mjs_getError(mjSpec* s) { mjCModel* modelC = reinterpret_cast(s->element); return modelC->GetError().message; } @@ -100,7 +100,7 @@ const char* mjm_getError(mjSpec* s) { // check if model has warnings -int mjm_isWarning(mjSpec* s) { +int mjs_isWarning(mjSpec* s) { mjCModel* modelC = reinterpret_cast(s->element); return modelC->GetError().warning; } @@ -108,7 +108,7 @@ int mjm_isWarning(mjSpec* s) { // delete model -void mjm_deleteSpec(mjSpec* s) { +void mjs_deleteSpec(mjSpec* s) { mjCModel* model = reinterpret_cast(s->element); delete model; } @@ -116,7 +116,7 @@ void mjm_deleteSpec(mjSpec* s) { // add child body to body, return child spec -mjmBody* mjm_addBody(mjmBody* bodyspec, mjmDefault* defspec) { +mjsBody* mjs_addBody(mjsBody* bodyspec, mjmDefault* defspec) { mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCBody* body = reinterpret_cast(bodyspec->element)->AddBody(def); return &body->spec; @@ -125,7 +125,7 @@ mjmBody* mjm_addBody(mjmBody* bodyspec, mjmDefault* defspec) { // add site to body, return site spec -mjmSite* mjm_addSite(mjmBody* bodyspec, mjmDefault* defspec) { +mjsSite* mjs_addSite(mjsBody* bodyspec, mjmDefault* defspec) { mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCBody* body = reinterpret_cast(bodyspec->element); mjCSite* site = body->AddSite(def); @@ -135,7 +135,7 @@ mjmSite* mjm_addSite(mjmBody* bodyspec, mjmDefault* defspec) { // add joint to body -mjmJoint* mjm_addJoint(mjmBody* bodyspec, mjmDefault* defspec) { +mjsJoint* mjs_addJoint(mjsBody* bodyspec, mjmDefault* defspec) { mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCBody* body = reinterpret_cast(bodyspec->element); mjCJoint* joint = body->AddJoint(def); @@ -145,7 +145,7 @@ mjmJoint* mjm_addJoint(mjmBody* bodyspec, mjmDefault* defspec) { // add free joint to body -mjmJoint* mjm_addFreeJoint(mjmBody* bodyspec) { +mjsJoint* mjs_addFreeJoint(mjsBody* bodyspec) { mjCBody* body = reinterpret_cast(bodyspec->element); mjCJoint* joint = body->AddFreeJoint(); return &joint->spec; @@ -154,7 +154,7 @@ mjmJoint* mjm_addFreeJoint(mjmBody* bodyspec) { // add geom to body -mjmGeom* mjm_addGeom(mjmBody* bodyspec, mjmDefault* defspec) { +mjsGeom* mjs_addGeom(mjsBody* bodyspec, mjmDefault* defspec) { mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCBody* body = reinterpret_cast(bodyspec->element); mjCGeom* geom = body->AddGeom(def); @@ -164,7 +164,7 @@ mjmGeom* mjm_addGeom(mjmBody* bodyspec, mjmDefault* defspec) { // add camera to body -mjmCamera* mjm_addCamera(mjmBody* bodyspec, mjmDefault* defspec) { +mjsCamera* mjs_addCamera(mjsBody* bodyspec, mjmDefault* defspec) { mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCBody* body = reinterpret_cast(bodyspec->element); mjCCamera* camera = body->AddCamera(def); @@ -174,7 +174,7 @@ mjmCamera* mjm_addCamera(mjmBody* bodyspec, mjmDefault* defspec) { // add light to body -mjmLight* mjm_addLight(mjmBody* bodyspec, mjmDefault* defspec) { +mjsLight* mjs_addLight(mjsBody* bodyspec, mjmDefault* defspec) { mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCBody* body = reinterpret_cast(bodyspec->element); mjCLight* light = body->AddLight(def); @@ -184,7 +184,7 @@ mjmLight* mjm_addLight(mjmBody* bodyspec, mjmDefault* defspec) { // add flex to model -mjmFlex* mjm_addFlex(mjSpec* s) { +mjsFlex* mjs_addFlex(mjSpec* s) { mjCModel* modelC = reinterpret_cast(s->element); mjCFlex* flex = modelC->AddFlex(); return &flex->spec; @@ -193,7 +193,7 @@ mjmFlex* mjm_addFlex(mjSpec* s) { // add frame to body -mjmFrame* mjm_addFrame(mjmBody* bodyspec, mjmFrame* parentframe) { +mjsFrame* mjs_addFrame(mjsBody* bodyspec, mjsFrame* parentframe) { mjCFrame* parentframeC = 0; if (parentframe) { parentframeC = reinterpret_cast(parentframe->element); @@ -207,7 +207,7 @@ mjmFrame* mjm_addFrame(mjmBody* bodyspec, mjmFrame* parentframe) { // add mesh to model -mjmMesh* mjm_addMesh(mjSpec* s, mjmDefault* defspec) { +mjsMesh* mjs_addMesh(mjSpec* s, mjmDefault* defspec) { mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCModel* modelC = reinterpret_cast(s->element); mjCMesh* mesh = modelC->AddMesh(def); @@ -217,7 +217,7 @@ mjmMesh* mjm_addMesh(mjSpec* s, mjmDefault* defspec) { // add height field to model -mjmHField* mjm_addHField(mjSpec* s) { +mjsHField* mjs_addHField(mjSpec* s) { mjCModel* modelC = reinterpret_cast(s->element); mjCHField* heightField = modelC->AddHField(); return &heightField->spec; @@ -226,7 +226,7 @@ mjmHField* mjm_addHField(mjSpec* s) { // add skin to model -mjmSkin* mjm_addSkin(mjSpec* s) { +mjsSkin* mjs_addSkin(mjSpec* s) { mjCModel* modelC = reinterpret_cast(s->element); mjCSkin* skin = modelC->AddSkin(); return &skin->spec; @@ -235,7 +235,7 @@ mjmSkin* mjm_addSkin(mjSpec* s) { // add texture to model -mjmTexture* mjm_addTexture(mjSpec* s) { +mjsTexture* mjs_addTexture(mjSpec* s) { mjCModel* modelC = reinterpret_cast(s->element); mjCTexture* texture = modelC->AddTexture(); return &texture->spec; @@ -244,7 +244,7 @@ mjmTexture* mjm_addTexture(mjSpec* s) { // add material to model -mjmMaterial* mjm_addMaterial(mjSpec* s, mjmDefault* defspec) { +mjsMaterial* mjs_addMaterial(mjSpec* s, mjmDefault* defspec) { mjCModel* modelC = reinterpret_cast(s->element); mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCMaterial* material = modelC->AddMaterial(def); @@ -254,7 +254,7 @@ mjmMaterial* mjm_addMaterial(mjSpec* s, mjmDefault* defspec) { // add pair to model -mjmPair* mjm_addPair(mjSpec* s, mjmDefault* defspec) { +mjsPair* mjs_addPair(mjSpec* s, mjmDefault* defspec) { mjCModel* modelC = reinterpret_cast(s->element); mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCPair* pair = modelC->AddPair(def); @@ -264,7 +264,7 @@ mjmPair* mjm_addPair(mjSpec* s, mjmDefault* defspec) { // add pair exclusion to model -mjmExclude* mjm_addExclude(mjSpec* s) { +mjsExclude* mjs_addExclude(mjSpec* s) { mjCModel* modelC = reinterpret_cast(s->element); mjCBodyPair* bodypair = modelC->AddExclude(); return &bodypair->spec; @@ -273,7 +273,7 @@ mjmExclude* mjm_addExclude(mjSpec* s) { // add equality to model -mjmEquality* mjm_addEquality(mjSpec* s, mjmDefault* defspec) { +mjsEquality* mjs_addEquality(mjSpec* s, mjmDefault* defspec) { mjCModel* modelC = reinterpret_cast(s->element); mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCEquality* equality = modelC->AddEquality(def); @@ -283,7 +283,7 @@ mjmEquality* mjm_addEquality(mjSpec* s, mjmDefault* defspec) { // add tendon to model -mjmTendon* mjm_addTendon(mjSpec* s, mjmDefault* defspec) { +mjsTendon* mjs_addTendon(mjSpec* s, mjmDefault* defspec) { mjCModel* modelC = reinterpret_cast(s->element); mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCTendon* tendon = modelC->AddTendon(def); @@ -293,7 +293,7 @@ mjmTendon* mjm_addTendon(mjSpec* s, mjmDefault* defspec) { // wrap site using tendon -MJAPI mjmWrap* mjm_wrapSite(mjmTendon* tendonspec, const char* name) { +MJAPI mjsWrap* mjs_wrapSite(mjsTendon* tendonspec, const char* name) { mjCTendon* tendon = reinterpret_cast(tendonspec->element); tendon->WrapSite(name); return &tendon->path.back()->spec; @@ -302,7 +302,7 @@ MJAPI mjmWrap* mjm_wrapSite(mjmTendon* tendonspec, const char* name) { // wrap geom using tendon -mjmWrap* mjm_wrapGeom(mjmTendon* tendonspec, const char* name, const char* sidesite) { +mjsWrap* mjs_wrapGeom(mjsTendon* tendonspec, const char* name, const char* sidesite) { mjCTendon* tendon = reinterpret_cast(tendonspec->element); tendon->WrapGeom(name, sidesite); return &tendon->path.back()->spec; @@ -311,7 +311,7 @@ mjmWrap* mjm_wrapGeom(mjmTendon* tendonspec, const char* name, const char* sides // wrap joint using tendon -mjmWrap* mjm_wrapJoint(mjmTendon* tendonspec, const char* name, double coef) { +mjsWrap* mjs_wrapJoint(mjsTendon* tendonspec, const char* name, double coef) { mjCTendon* tendon = reinterpret_cast(tendonspec->element); tendon->WrapJoint(name, coef); return &tendon->path.back()->spec; @@ -320,7 +320,7 @@ mjmWrap* mjm_wrapJoint(mjmTendon* tendonspec, const char* name, double coef) { // wrap pulley using tendon -mjmWrap* mjm_wrapPulley(mjmTendon* tendonspec, double divisor) { +mjsWrap* mjs_wrapPulley(mjsTendon* tendonspec, double divisor) { mjCTendon* tendon = reinterpret_cast(tendonspec->element); tendon->WrapPulley(divisor); return &tendon->path.back()->spec; @@ -329,7 +329,7 @@ mjmWrap* mjm_wrapPulley(mjmTendon* tendonspec, double divisor) { // add actuator to model -mjmActuator* mjm_addActuator(mjSpec* s, mjmDefault* defspec) { +mjsActuator* mjs_addActuator(mjSpec* s, mjmDefault* defspec) { mjCModel* modelC = reinterpret_cast(s->element); mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCActuator* actuator = modelC->AddActuator(def); @@ -339,7 +339,7 @@ mjmActuator* mjm_addActuator(mjSpec* s, mjmDefault* defspec) { // add sensor to model -mjmSensor* mjm_addSensor(mjSpec* s) { +mjsSensor* mjs_addSensor(mjSpec* s) { mjCModel* modelC = reinterpret_cast(s->element); mjCSensor* sensor = modelC->AddSensor(); return &sensor->spec; @@ -348,7 +348,7 @@ mjmSensor* mjm_addSensor(mjSpec* s) { // add numeric to model -mjmNumeric* mjm_addNumeric(mjSpec* s) { +mjsNumeric* mjs_addNumeric(mjSpec* s) { mjCModel* modelC = reinterpret_cast(s->element); mjCNumeric* numeric = modelC->AddNumeric(); return &numeric->spec; @@ -357,7 +357,7 @@ mjmNumeric* mjm_addNumeric(mjSpec* s) { // add text to model -mjmText* mjm_addText(mjSpec* s) { +mjsText* mjs_addText(mjSpec* s) { mjCModel* modelC = reinterpret_cast(s->element); mjCText* text = modelC->AddText(); return &text->spec; @@ -366,7 +366,7 @@ mjmText* mjm_addText(mjSpec* s) { // add tuple to model -mjmTuple* mjm_addTuple(mjSpec* s) { +mjsTuple* mjs_addTuple(mjSpec* s) { mjCModel* modelC = reinterpret_cast(s->element); mjCTuple* tuple = modelC->AddTuple(); return &tuple->spec; @@ -375,7 +375,7 @@ mjmTuple* mjm_addTuple(mjSpec* s) { // add keyframe to model -mjmKey* mjm_addKey(mjSpec* s) { +mjsKey* mjs_addKey(mjSpec* s) { mjCModel* modelC = reinterpret_cast(s->element); mjCKey* key = modelC->AddKey(); return &key->spec; @@ -384,7 +384,7 @@ mjmKey* mjm_addKey(mjSpec* s) { // add plugin to model -mjmPlugin* mjm_addPlugin(mjSpec* s) { +mjsPlugin* mjs_addPlugin(mjSpec* s) { mjCModel* modelC = reinterpret_cast(s->element); mjCPlugin* plugin = modelC->AddPlugin(); plugin->spec.instance = (mjElement)plugin; @@ -394,7 +394,7 @@ mjmPlugin* mjm_addPlugin(mjSpec* s) { // add default to model -mjmDefault* mjm_addDefault(mjSpec* s, const char* classname, int parentid, int* id) { +mjmDefault* mjs_addDefault(mjSpec* s, const char* classname, int parentid, int* id) { mjCModel* modelC = reinterpret_cast(s->element); *id = (int)modelC->defaults.size(); mjCDef* def = modelC->AddDef(classname, parentid); @@ -408,21 +408,21 @@ mjmDefault* mjm_addDefault(mjSpec* s, const char* classname, int parentid, int* // get objects -mjSpec* mjm_getSpec(mjmBody* body) { +mjSpec* mjs_getSpec(mjsBody* body) { return &(reinterpret_cast(body->element)->model->spec); } // get default -mjmDefault* mjm_getDefault(mjElement element) { +mjmDefault* mjs_getDefault(mjElement element) { return &(reinterpret_cast(element)->def->spec); } // Find default with given name in model. -mjmDefault* mjm_findDefault(mjSpec* s, const char* classname) { +mjmDefault* mjs_findDefault(mjSpec* s, const char* classname) { mjCModel* modelC = reinterpret_cast(s->element); mjCDef* cdef = modelC->FindDef(classname); if (!cdef) { @@ -434,7 +434,7 @@ mjmDefault* mjm_findDefault(mjSpec* s, const char* classname) { // get default[0] from model -mjmDefault* mjm_getSpecDefault(mjSpec* s) { +mjmDefault* mjs_getSpecDefault(mjSpec* s) { mjCModel* modelC = reinterpret_cast(s->element); mjCDef* def = modelC->defaults[0]; if (!def) { @@ -446,7 +446,7 @@ mjmDefault* mjm_getSpecDefault(mjSpec* s) { // find body in model by name -mjmBody* mjm_findBody(mjSpec* s, const char* name) { +mjsBody* mjs_findBody(mjSpec* s, const char* name) { mjCModel* model = reinterpret_cast(s->element); mjCBase* body = 0; if (model->IsCompiled()) { @@ -460,7 +460,7 @@ mjmBody* mjm_findBody(mjSpec* s, const char* name) { // find child of a body by name -mjmBody* mjm_findChild(mjmBody* bodyspec, const char* name) { +mjsBody* mjs_findChild(mjsBody* bodyspec, const char* name) { mjCBody* body = reinterpret_cast(bodyspec->element); mjCBase* child = body->FindObject(mjOBJ_BODY, std::string(name)); return child ? &(static_cast(child)->spec) : nullptr; @@ -469,7 +469,7 @@ mjmBody* mjm_findChild(mjmBody* bodyspec, const char* name) { // find mesh by name -mjmMesh* mjm_findMesh(mjSpec* s, const char* name) { +mjsMesh* mjs_findMesh(mjSpec* s, const char* name) { mjCModel* model = reinterpret_cast(s->element); mjCMesh* mesh = (mjCMesh*)model->FindObject(mjOBJ_MESH, std::string(name)); return mesh ? &(static_cast(mesh)->spec) : nullptr; @@ -478,7 +478,7 @@ mjmMesh* mjm_findMesh(mjSpec* s, const char* name) { // find frame by name -mjmFrame* mjm_findFrame(mjSpec* s, const char* name) { +mjsFrame* mjs_findFrame(mjSpec* s, const char* name) { mjCModel* model = reinterpret_cast(s->element); mjCFrame* frame = (mjCFrame*)model->FindFrame(model->GetWorld(), std::string(name)); return frame ? &(static_cast(frame)->spec) : nullptr; @@ -487,7 +487,7 @@ mjmFrame* mjm_findFrame(mjSpec* s, const char* name) { // set frame -void mjm_setFrame(mjElement dest, mjmFrame* frame) { +void mjs_setFrame(mjElement dest, mjsFrame* frame) { if (!frame) { return; } @@ -499,14 +499,14 @@ void mjm_setFrame(mjElement dest, mjmFrame* frame) { // get id -int mjm_getId(mjElement element) { +int mjs_getId(mjElement element) { return reinterpret_cast(element)->id; } // set default -void mjm_setDefault(mjElement element, mjmDefault* defspec) { +void mjs_setDefault(mjElement element, mjmDefault* defspec) { mjCBase* baseC = reinterpret_cast(element); baseC->def = reinterpret_cast(defspec->element); } @@ -514,7 +514,7 @@ void mjm_setDefault(mjElement element, mjmDefault* defspec) { // set string -void mjm_setString(mjString dest, const char* text) { +void mjs_setString(mjString dest, const char* text) { std::string* str = reinterpret_cast(dest); *str = std::string(text); } @@ -522,10 +522,10 @@ void mjm_setString(mjString dest, const char* text) { // Set specific entry in destination string vector. -mjtByte mjm_setInStringVec(mjStringVec dest, int i, const char* text) { +mjtByte mjs_setInStringVec(mjStringVec dest, int i, const char* text) { std::vector* v = reinterpret_cast*>(dest); if (v->size() <= i) { - mju_error("Requested index in mjm_setInStringVec is out of bounds"); + mju_error("Requested index in mjs_setInStringVec is out of bounds"); return 0; } v->at(i) = std::string(text); @@ -535,7 +535,7 @@ mjtByte mjm_setInStringVec(mjStringVec dest, int i, const char* text) { // split text and copy into string array -void mjm_setStringVec(mjStringVec dest, const char* text) { +void mjs_setStringVec(mjStringVec dest, const char* text) { std::vector* v = reinterpret_cast*>(dest); *v = mjXUtil::String2Vector(text); } @@ -543,14 +543,14 @@ void mjm_setStringVec(mjStringVec dest, const char* text) { // add text entry to destination string vector -void mjm_appendString(mjStringVec dest, const char* text) { +void mjs_appendString(mjStringVec dest, const char* text) { std::vector* v = reinterpret_cast*>(dest); v->push_back(std::string(text)); } // copy int array to vector -void mjm_setInt(mjIntVec dest, const int* array, int size) { +void mjs_setInt(mjIntVec dest, const int* array, int size) { std::vector* v = reinterpret_cast*>(dest); v->assign(size, 0.0); for (int i = 0; i < size; ++i) { @@ -561,7 +561,7 @@ void mjm_setInt(mjIntVec dest, const int* array, int size) { // append int array to vector of arrays -void mjm_appendIntVec(mjIntVecVec dest, const int* array, int size) { +void mjs_appendIntVec(mjIntVecVec dest, const int* array, int size) { std::vector>* v = reinterpret_cast>*>(dest); v->push_back(std::vector(array, array + size)); } @@ -569,7 +569,7 @@ void mjm_appendIntVec(mjIntVecVec dest, const int* array, int size) { // copy float array to vector -void mjm_setFloat(mjFloatVec dest, const float* array, int size) { +void mjs_setFloat(mjFloatVec dest, const float* array, int size) { std::vector* v = reinterpret_cast*>(dest); v->assign(size, 0.0); for (int i = 0; i < size; ++i) { @@ -581,7 +581,7 @@ void mjm_setFloat(mjFloatVec dest, const float* array, int size) { // append float array to vector of arrays -void mjm_appendFloatVec(mjFloatVecVec dest, const float* array, int size) { +void mjs_appendFloatVec(mjFloatVecVec dest, const float* array, int size) { std::vector>* v = reinterpret_cast>*>(dest); v->push_back(std::vector(array, array + size)); } @@ -589,7 +589,7 @@ void mjm_appendFloatVec(mjFloatVecVec dest, const float* array, int size) { // copy double array to vector -void mjm_setDouble(mjDoubleVec dest, const double* array, int size) { +void mjs_setDouble(mjDoubleVec dest, const double* array, int size) { std::vector* v = reinterpret_cast*>(dest); v->assign(size, 0.0); for (int i = 0; i < size; ++i) { @@ -600,7 +600,7 @@ void mjm_setDouble(mjDoubleVec dest, const double* array, int size) { // get string -const char* mjm_getString(const mjString source) { +const char* mjs_getString(const mjString source) { std::string* str = reinterpret_cast(source); if (!str) { return nullptr; @@ -611,7 +611,7 @@ const char* mjm_getString(const mjString source) { // get double array -const double* mjm_getDouble(const mjDoubleVec source, int* size) { +const double* mjs_getDouble(const mjDoubleVec source, int* size) { std::vector* v = reinterpret_cast*>(source); if (size) { *size = v->size(); @@ -622,7 +622,7 @@ const double* mjm_getDouble(const mjDoubleVec source, int* size) { // set plugin attributes -void mjm_setPluginAttributes(mjmPlugin* plugin, void* attributes) { +void mjs_setPluginAttributes(mjsPlugin* plugin, void* attributes) { mjCPlugin* pluginC = reinterpret_cast(plugin->instance); std::map>* config_attribs = reinterpret_cast>*>(attributes); @@ -632,7 +632,7 @@ void mjm_setPluginAttributes(mjmPlugin* plugin, void* attributes) { // Set active plugins. -void mjm_setActivePlugins(mjSpec* s, void* activeplugins) { +void mjs_setActivePlugins(mjSpec* s, void* activeplugins) { mjCModel* modelC = reinterpret_cast(s->element); std::vector>* active_plugins = reinterpret_cast>*>(activeplugins); @@ -642,7 +642,7 @@ void mjm_setActivePlugins(mjSpec* s, void* activeplugins) { // compute full inertia -const char* mjm_setFullInertia(mjmBody* bodyspec, double quat[4], double inertia[3]) { +const char* mjs_setFullInertia(mjsBody* bodyspec, double quat[4], double inertia[3]) { mjCBody* body = reinterpret_cast(bodyspec->element); return body->FullInertia(quat, inertia); } diff --git a/src/user/user_api.h b/src/user/user_api.h index 3e79c1c8..b78c8495 100644 --- a/src/user/user_api.h +++ b/src/user/user_api.h @@ -135,25 +135,25 @@ typedef struct _mjSpec { // model specification } mjSpec; -typedef struct _mjmOrientation { // alternative orientation specifiers +typedef struct _mjsOrientation { // alternative orientation specifiers double axisangle[4]; // rotation axis and angle double xyaxes[6]; // x and y axes double zaxis[3]; // z axis (use minimal rotation) double euler[3]; // euler angles -} mjmOrientation; +} mjsOrientation; -typedef struct _mjmPlugin { // plugin specification +typedef struct _mjsPlugin { // plugin specification mjElement instance; // internal, do not modify mjString name; // name mjString instance_name; // instance name int plugin_slot; // global registered slot number of the plugin mjtByte active; // is the plugin active mjString info; // message appended to compiler errors -} mjmPlugin; +} mjsPlugin; -typedef struct _mjmBody { // body specification +typedef struct _mjsBody { // body specification mjElement element; // internal, do not modify mjString name; // name mjString childclass; // childclass name @@ -161,14 +161,14 @@ typedef struct _mjmBody { // body specification // body frame double pos[3]; // frame position double quat[4]; // frame orientation - mjmOrientation alt; // frame alternative orientation + mjsOrientation alt; // frame alternative orientation // inertial frame double mass; // mass double ipos[3]; // inertial frame position double iquat[4]; // inertial frame orientation double inertia[3]; // diagonal inertia (in i-frame) - mjmOrientation ialt; // inertial frame alternative orientation + mjsOrientation ialt; // inertial frame alternative orientation double fullinertia[6]; // non-axis-aligned inertia matrix // other @@ -176,23 +176,23 @@ typedef struct _mjmBody { // body specification double gravcomp; // gravity compensation mjDoubleVec userdata; // user data mjtByte explicitinertial; // whether to save the body with explicit inertial clause - mjmPlugin plugin; // passive force plugin + mjsPlugin plugin; // passive force plugin mjString info; // message appended to compiler errors -} mjmBody; +} mjsBody; -typedef struct _mjmFrame { // frame specification +typedef struct _mjsFrame { // frame specification mjElement element; // internal, do not modify mjString name; // name mjString childclass; // childclass name double pos[3]; // position double quat[4]; // orientation - mjmOrientation alt; // alternative orientation + mjsOrientation alt; // alternative orientation mjString info; // message appended to compiler errors -} mjmFrame; +} mjsFrame; -typedef struct _mjmJoint { // joint specification +typedef struct _mjsJoint { // joint specification mjElement element; // internal, do not modify mjString name; // name mjString classname; // class name @@ -229,10 +229,10 @@ typedef struct _mjmJoint { // joint specification double urdfeffort; // effort (urdf) mjDoubleVec userdata; // user data mjString info; // message appended to compiler errors -} mjmJoint; +} mjsJoint; -typedef struct _mjmGeom { // geom specification +typedef struct _mjsGeom { // geom specification mjElement element; // internal, do not modify mjString name; // name mjString classname; // classname @@ -241,7 +241,7 @@ typedef struct _mjmGeom { // geom specification // frame, size double pos[3]; // position double quat[4]; // orientation - mjmOrientation alt; // alternative orientation + mjsOrientation alt; // alternative orientation double fromto[6]; // alternative for capsule, cylinder, box, ellipsoid double size[3]; // type-specific size @@ -276,12 +276,12 @@ typedef struct _mjmGeom { // geom specification mjString meshname; // mesh attached to geom double fitscale; // scale mesh uniformly mjDoubleVec userdata; // user data - mjmPlugin plugin; // sdf plugin + mjsPlugin plugin; // sdf plugin mjString info; // message appended to compiler errors -} mjmGeom; +} mjsGeom; -typedef struct _mjmSite { // site specification +typedef struct _mjsSite { // site specification mjElement element; // internal, do not modify mjString name; // name mjString classname; // class name @@ -289,7 +289,7 @@ typedef struct _mjmSite { // site specification // frame, size double pos[3]; // position double quat[4]; // orientation - mjmOrientation alt; // alternative orientation + mjsOrientation alt; // alternative orientation double fromto[6]; // alternative for capsule, cylinder, box, ellipsoid double size[3]; // geom size @@ -302,10 +302,10 @@ typedef struct _mjmSite { // site specification // other mjDoubleVec userdata; // user data mjString info; // message appended to compiler errors -} mjmSite; +} mjsSite; -typedef struct _mjmCamera { // camera specification +typedef struct _mjsCamera { // camera specification mjElement element; // internal, do not modify mjString name; // name mjString classname; // class name @@ -313,7 +313,7 @@ typedef struct _mjmCamera { // camera specification // extrinsics double pos[3]; // position double quat[4]; // orientation - mjmOrientation alt; // alternative orientation + mjsOrientation alt; // alternative orientation mjtCamLight mode; // tracking mode mjString targetbody; // target body for tracking/targeting @@ -331,10 +331,10 @@ typedef struct _mjmCamera { // camera specification // other mjDoubleVec userdata; // user data mjString info; // message appended to compiler errors -} mjmCamera; +} mjsCamera; -typedef struct _mjmLight { // light specification +typedef struct _mjsLight { // light specification mjElement element; // internal, do not modify mjString name; // name mjString classname; // class name @@ -358,10 +358,10 @@ typedef struct _mjmLight { // light specification // other mjString info; // message appended to compiler errors -} mjmLight; +} mjsLight; -typedef struct _mjmFlex { +typedef struct _mjsFlex { mjElement element; // internal, do not modify mjString name; // name mjString classname; // class name @@ -399,10 +399,10 @@ typedef struct _mjmFlex { // other mjString info; // message appended to compiler errors -} mjmFlex; +} mjsFlex; -typedef struct _mjmMesh { // mesh specification +typedef struct _mjsMesh { // mesh specification mjElement element; // internal, do not modify mjString name; // name mjString classname; // class name @@ -418,12 +418,12 @@ typedef struct _mjmMesh { // mesh specification mjIntVec userface; // user vertex indices mjIntVec userfacenormal; // user normal indices mjIntVec userfacetexcoord; // user texcoord indices - mjmPlugin plugin; // sdf plugin + mjsPlugin plugin; // sdf plugin mjString info; // message appended to compiler errors -} mjmMesh; +} mjsMesh; -typedef struct _mjmHField { // height field specification +typedef struct _mjsHField { // height field specification mjElement element; // internal, do not modify mjString name; // name mjString content_type; // content type of file @@ -433,11 +433,11 @@ typedef struct _mjmHField { // height field specification int ncol; // number of columns mjFloatVec userdata; // user-provided elevation data mjString info; // message appended to compiler errors -} mjmHField; +} mjsHField; -typedef struct _mjmSkin { // skin specification +typedef struct _mjsSkin { // skin specification mjElement element; // internal, do not modify mjString name; // name mjString classname; // class name @@ -461,10 +461,10 @@ typedef struct _mjmSkin { // skin specification // other mjString info; // message appended to compiler errors -} mjmSkin; +} mjsSkin; -typedef struct _mjmTexture { // texture specification +typedef struct _mjsTexture { // texture specification mjElement element; // internal, do not modify mjString name; // name mjString classname; // class name @@ -495,10 +495,10 @@ typedef struct _mjmTexture { // texture specification // other mjString info; // message appended to compiler errors -} mjmTexture; +} mjsTexture; -typedef struct _mjmMaterial { // material specification +typedef struct _mjsMaterial { // material specification mjElement element; // internal, do not modify mjString name; // name mjString classname; // class name @@ -511,10 +511,10 @@ typedef struct _mjmMaterial { // material specification float reflectance; // reflectance float rgba[4]; // rgba mjString info; // message appended to compiler errors -} mjmMaterial; +} mjsMaterial; -typedef struct _mjmPair { +typedef struct _mjsPair { mjElement element; // internal, do not modify mjString name; // name mjString classname; // class name @@ -530,19 +530,19 @@ typedef struct _mjmPair { double gap; // include in solver if distfullinertia. -MJAPI const char* mjm_setFullInertia(mjmBody* body, double quat[4], double inertia[3]); +MJAPI const char* mjs_setFullInertia(mjsBody* body, double quat[4], double inertia[3]); //---------------------------------- Initialization functions -------------------------------------- // Default model attributes. -MJAPI void mjm_defaultSpec(mjSpec& model); +MJAPI void mjs_defaultSpec(mjSpec& model); // Default body attributes. -MJAPI void mjm_defaultBody(mjmBody& body); +MJAPI void mjs_defaultBody(mjsBody& body); // Default frame attributes. -MJAPI void mjm_defaultFrame(mjmFrame& frame); +MJAPI void mjs_defaultFrame(mjsFrame& frame); // Default joint attributes. -MJAPI void mjm_defaultJoint(mjmJoint& joint); +MJAPI void mjs_defaultJoint(mjsJoint& joint); // Default geom attributes. -MJAPI void mjm_defaultGeom(mjmGeom& geom); +MJAPI void mjs_defaultGeom(mjsGeom& geom); // Default site attributes. -MJAPI void mjm_defaultSite(mjmSite& site); +MJAPI void mjs_defaultSite(mjsSite& site); // Default camera attributes. -MJAPI void mjm_defaultCamera(mjmCamera& camera); +MJAPI void mjs_defaultCamera(mjsCamera& camera); // Default light attributes. -MJAPI void mjm_defaultLight(mjmLight& light); +MJAPI void mjs_defaultLight(mjsLight& light); // Default flex attributes. -MJAPI void mjm_defaultFlex(mjmFlex& flex); +MJAPI void mjs_defaultFlex(mjsFlex& flex); // Default mesh attributes. -MJAPI void mjm_defaultMesh(mjmMesh& mesh); +MJAPI void mjs_defaultMesh(mjsMesh& mesh); // Default height field attributes. -MJAPI void mjm_defaultHField(mjmHField& hfield); +MJAPI void mjs_defaultHField(mjsHField& hfield); // Default skin attributes. -MJAPI void mjm_defaultSkin(mjmSkin& skin); +MJAPI void mjs_defaultSkin(mjsSkin& skin); // Default texture attributes. -MJAPI void mjm_defaultTexture(mjmTexture& texture); +MJAPI void mjs_defaultTexture(mjsTexture& texture); // Default material attributes. -MJAPI void mjm_defaultMaterial(mjmMaterial& material); +MJAPI void mjs_defaultMaterial(mjsMaterial& material); // Default pair attributes. -MJAPI void mjm_defaultPair(mjmPair& pair); +MJAPI void mjs_defaultPair(mjsPair& pair); // Default equality attributes. -MJAPI void mjm_defaultEquality(mjmEquality& equality); +MJAPI void mjs_defaultEquality(mjsEquality& equality); // Default tendon attributes. -MJAPI void mjm_defaultTendon(mjmTendon& tendon); +MJAPI void mjs_defaultTendon(mjsTendon& tendon); // Default actuator attributes. -MJAPI void mjm_defaultActuator(mjmActuator& actuator); +MJAPI void mjs_defaultActuator(mjsActuator& actuator); // Default sensor attributes. -MJAPI void mjm_defaultSensor(mjmSensor& sensor); +MJAPI void mjs_defaultSensor(mjsSensor& sensor); // Default numeric attributes. -MJAPI void mjm_defaultNumeric(mjmNumeric& numeric); +MJAPI void mjs_defaultNumeric(mjsNumeric& numeric); // Default text attributes. -MJAPI void mjm_defaultText(mjmText& text); +MJAPI void mjs_defaultText(mjsText& text); // Default tuple attributes. -MJAPI void mjm_defaultTuple(mjmTuple& tuple); +MJAPI void mjs_defaultTuple(mjsTuple& tuple); // Default keyframe attributes. -MJAPI void mjm_defaultKey(mjmKey& key); +MJAPI void mjs_defaultKey(mjsKey& key); // Default plugin attributes. -MJAPI void mjm_defaultPlugin(mjmPlugin& plugin); +MJAPI void mjs_defaultPlugin(mjsPlugin& plugin); //------------------------- Cache functions ------------------------------------ diff --git a/src/user/user_composite.cc b/src/user/user_composite.cc index 15a77caf..4337557d 100644 --- a/src/user/user_composite.cc +++ b/src/user/user_composite.cc @@ -66,7 +66,7 @@ mjCComposite::mjCComposite(void) { mj_defaultSolRefImp(solrefsmooth, solimpsmooth); // plugin variables - mjm_defaultPlugin(plugin); + mjs_defaultPlugin(plugin); plugin_name = ""; plugin_instance_name = ""; plugin.name = (mjString)&plugin_name; @@ -223,7 +223,7 @@ void mjCComposite::SetDefault(void) { // make composite object -bool mjCComposite::Make(mjSpec* spec, mjmBody* body, char* error, int error_sz) { +bool mjCComposite::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) { mjCModel* model = (mjCModel*)spec->element; // check geom type @@ -350,7 +350,7 @@ bool mjCComposite::Make(mjSpec* spec, mjmBody* body, char* error, int error_sz) -bool mjCComposite::MakeParticle(mjCModel* model, mjmBody* body, char* error, int error_sz) { +bool mjCComposite::MakeParticle(mjCModel* model, mjsBody* body, char* error, int error_sz) { char txt[100]; std::vector face; @@ -464,13 +464,13 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjmBody* body, char* error, int // create bodies and geoms for (int i=0; iname, username[i].c_str()); + mjs_setString(b->name, username[i].c_str()); } else { mju::sprintf_arr(txt, "%sB%d", prefix.c_str(), i); - mjm_setString(b->name, txt); + mjs_setString(b->name, txt); } // set body position @@ -481,8 +481,8 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjmBody* body, char* error, int // add slider joints if none defined if (!add[mjCOMPKIND_PARTICLE]) { for (int i=0; i<3; i++) { - mjmJoint* jnt = mjm_addJoint(b, &defjoint[mjCOMPKIND_JOINT][0].spec); - mjm_setDefault(jnt->element, mjm_getDefault(body->element)); + mjsJoint* jnt = mjs_addJoint(b, &defjoint[mjCOMPKIND_JOINT][0].spec); + mjs_setDefault(jnt->element, mjs_getDefault(body->element)); jnt->type = mjJNT_SLIDE; mjuu_setvec(jnt->pos, 0, 0, 0); mjuu_setvec(jnt->axis, 0, 0, 0); @@ -493,30 +493,30 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjmBody* body, char* error, int // add user-specified joints else { for (auto defjnt : defjoint[mjCOMPKIND_PARTICLE]) { - mjmJoint* jnt = mjm_addJoint(b, &defjnt.spec); - mjm_setDefault(jnt->element, mjm_getDefault(body->element)); + mjsJoint* jnt = mjs_addJoint(b, &defjnt.spec); + mjs_setDefault(jnt->element, mjs_getDefault(body->element)); } } // add geom - mjmGeom* g = mjm_addGeom(b, &def[0].spec); - mjm_setDefault(g->element, mjm_getDefault(body->element)); + mjsGeom* g = mjs_addGeom(b, &def[0].spec); + mjs_setDefault(g->element, mjs_getDefault(body->element)); // add site - mjmSite* s = mjm_addSite(b, &def[0].spec); - mjm_setDefault(s->element, mjm_getDefault(body->element)); + mjsSite* s = mjs_addSite(b, &def[0].spec); + mjs_setDefault(s->element, mjs_getDefault(body->element)); s->type = mjGEOM_SPHERE; mju::sprintf_arr(txt, "%sS%d", prefix.c_str(), i); - mjm_setString(s->name, txt); + mjs_setString(s->name, txt); // add plugin if (plugin.active) { - mjmPlugin* pplugin = &b->plugin; + mjsPlugin* pplugin = &b->plugin; mjCPlugin* cplugin = (mjCPlugin*)plugin.instance; pplugin->active = true; pplugin->instance = (mjElement)plugin.instance; - mjm_setString(pplugin->instance_name, plugin_instance_name.c_str()); - mjm_setString(pplugin->name, mjm_getString(plugin.name)); + mjs_setString(pplugin->instance_name, plugin_instance_name.c_str()); + mjs_setString(pplugin->name, mjs_getString(plugin.name)); if (i==0 && !cplugin->config_attribs["face"].empty()) { return comperr(error, "Face attribute already exists in plugin", error_sz); @@ -560,18 +560,18 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjmBody* body, char* error, int mju::sprintf_arr(txt2, "%sS%d", prefix.c_str(), v1); // create tendon - mjmTendon* ten = mjm_addTendon(&model->spec, &def[mjCOMPKIND_TENDON].spec); - mjm_setDefault(ten->element, &model->defaults[0]->spec); - mjm_setString(ten->name, txt0); + mjsTendon* ten = mjs_addTendon(&model->spec, &def[mjCOMPKIND_TENDON].spec); + mjs_setDefault(ten->element, &model->defaults[0]->spec); + mjs_setString(ten->name, txt0); ten->group = 4; - mjm_wrapSite(ten, txt1); - mjm_wrapSite(ten, txt2); + mjs_wrapSite(ten, txt1); + mjs_wrapSite(ten, txt2); // add equality constraint - mjmEquality* eq = mjm_addEquality(&model->spec, &def[mjCOMPKIND_TENDON].spec); - mjm_setDefault(eq->element, &model->defaults[0]->spec); + mjsEquality* eq = mjs_addEquality(&model->spec, &def[mjCOMPKIND_TENDON].spec); + mjs_setDefault(eq->element, &model->defaults[0]->spec); eq->type = mjEQ_TENDON; - mjm_setString(eq->name1, mjm_getString(ten->name)); + mjs_setString(eq->name1, mjs_getString(ten->name)); } } @@ -593,7 +593,7 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjmBody* body, char* error, int // make grid connected with tendons -bool mjCComposite::MakeGrid(mjCModel* model, mjmBody* body, char* error, int error_sz) { +bool mjCComposite::MakeGrid(mjCModel* model, mjsBody* body, char* error, int error_sz) { char txt[100], txt1[100], txt2[100]; // check dimensionality @@ -615,9 +615,9 @@ bool mjCComposite::MakeGrid(mjCModel* model, mjmBody* body, char* error, int err for (int ix=0; ixname, txt); + mjs_setString(b->name, txt); // set body position b->pos[0] = offset[0] + spacing*(ix - 0.5*count[0]); @@ -625,18 +625,18 @@ bool mjCComposite::MakeGrid(mjCModel* model, mjmBody* body, char* error, int err b->pos[2] = offset[2]; // add geom - mjmGeom* g = mjm_addGeom(b, &def[0].spec); - mjm_setDefault(g->element, mjm_getDefault(body->element)); + mjsGeom* g = mjs_addGeom(b, &def[0].spec); + mjs_setDefault(g->element, mjs_getDefault(body->element)); g->type = mjGEOM_SPHERE; mju::sprintf_arr(txt, "%sG%d_%d", prefix.c_str(), ix, iy); - mjm_setString(g->name, txt); + mjs_setString(g->name, txt); // add site - mjmSite* s = mjm_addSite(b, &def[0].spec); - mjm_setDefault(s->element, mjm_getDefault(body->element)); + mjsSite* s = mjs_addSite(b, &def[0].spec); + mjs_setDefault(s->element, mjs_getDefault(body->element)); s->type = mjGEOM_SPHERE; mju::sprintf_arr(txt, "%sS%d_%d", prefix.c_str(), ix, iy); - mjm_setString(s->name, txt); + mjs_setString(s->name, txt); // skip pinned elements bool skip = false; @@ -651,12 +651,12 @@ bool mjCComposite::MakeGrid(mjCModel* model, mjmBody* body, char* error, int err } // add slider joint - mjmJoint* jnt[3]; + mjsJoint* jnt[3]; for (int i=0; i<3; i++) { - jnt[i] = mjm_addJoint(b, &defjoint[mjCOMPKIND_JOINT][0].spec); - mjm_setDefault(jnt[i]->element, mjm_getDefault(body->element)); + jnt[i] = mjs_addJoint(b, &defjoint[mjCOMPKIND_JOINT][0].spec); + mjs_setDefault(jnt[i]->element, mjs_getDefault(body->element)); mju::sprintf_arr(txt, "%sJ%d_%d_%d", prefix.c_str(), i, ix, iy); - mjm_setString(jnt[i]->name, txt); + mjs_setString(jnt[i]->name, txt); jnt[i]->type = mjJNT_SLIDE; mjuu_setvec(jnt[i]->pos, 0, 0, 0); mjuu_setvec(jnt[i]->axis, 0, 0, 0); @@ -682,10 +682,10 @@ bool mjCComposite::MakeGrid(mjCModel* model, mjmBody* body, char* error, int err ten->WrapSite(txt2); // add equality constraint - mjmEquality* eq = mjm_addEquality(&model->spec, &def[mjCOMPKIND_TENDON].spec); - mjm_setDefault(eq->element, &model->defaults[0]->spec); + mjsEquality* eq = mjs_addEquality(&model->spec, &def[mjCOMPKIND_TENDON].spec); + mjs_setDefault(eq->element, &model->defaults[0]->spec); eq->type = mjEQ_TENDON; - mjm_setString(eq->name1, ten->name.c_str()); + mjs_setString(eq->name1, ten->name.c_str()); } } } @@ -709,7 +709,7 @@ bool mjCComposite::MakeGrid(mjCModel* model, mjmBody* body, char* error, int err -bool mjCComposite::MakeCable(mjCModel* model, mjmBody* body, char* error, int error_sz) { +bool mjCComposite::MakeCable(mjCModel* model, mjsBody* body, char* error, int error_sz) { // check dim if (dim!=1) { return comperr(error, "Cable must be one-dimensional", error_sz); @@ -723,9 +723,9 @@ bool mjCComposite::MakeCable(mjCModel* model, mjmBody* body, char* error, int er } // add name to model - mjmText* pte = mjm_addText(&model->spec); - mjm_setString(pte->name, ("composite_" + prefix).c_str()); - mjm_setString(pte->data, ("rope_" + prefix).c_str()); + mjsText* pte = mjs_addText(&model->spec); + mjs_setString(pte->name, ("composite_" + prefix).c_str()); + mjs_setString(pte->data, ("rope_" + prefix).c_str()); // populate uservert if not specified if (uservert.empty()) { @@ -780,7 +780,7 @@ bool mjCComposite::MakeCable(mjCModel* model, mjmBody* body, char* error, int er -mjmBody* mjCComposite::AddCableBody(mjCModel* model, mjmBody* body, int ix, mjtNum normal[3], mjtNum prev_quat[4]) { +mjsBody* mjCComposite::AddCableBody(mjCModel* model, mjsBody* body, int ix, mjtNum normal[3], mjtNum prev_quat[4]) { char txt_geom[100], txt_site[100], txt_slide[100]; char this_body[100], next_body[100], this_joint[100]; mjtNum dquat[4], this_quat[4]; @@ -836,8 +836,8 @@ mjmBody* mjCComposite::AddCableBody(mjCModel* model, mjmBody* body, int ix, mjtN mju::sprintf_arr(txt_slide, "%sJs%d", prefix.c_str(), ix); // add body - body = mjm_addBody(body, 0); - mjm_setString(body->name, this_body); + body = mjs_addBody(body, 0); + mjs_setString(body->name, this_body); if (first) { mjuu_setvec(body->pos, offset[0]+uservert[3*ix], offset[1]+uservert[3*ix+1], @@ -851,9 +851,9 @@ mjmBody* mjCComposite::AddCableBody(mjCModel* model, mjmBody* body, int ix, mjtN } // add geom - mjmGeom* geom = mjm_addGeom(body, &def[0].spec); - mjm_setDefault(geom->element, mjm_getDefault(body->element)); - mjm_setString(geom->name, txt_geom); + mjsGeom* geom = mjs_addGeom(body, &def[0].spec); + mjs_setDefault(geom->element, mjs_getDefault(body->element)); + mjs_setString(geom->name, txt_geom); if (def[0].spec.geom->type==mjGEOM_CYLINDER || def[0].spec.geom->type==mjGEOM_CAPSULE) { mjuu_zerovec(geom->fromto, 6); @@ -866,11 +866,11 @@ mjmBody* mjCComposite::AddCableBody(mjCModel* model, mjmBody* body, int ix, mjtN // add plugin if (plugin.active) { - mjmPlugin* pplugin = &body->plugin; + mjsPlugin* pplugin = &body->plugin; pplugin->active = true; pplugin->instance = (mjElement)plugin.instance; - mjm_setString(pplugin->name, mjm_getString(plugin.name)); - mjm_setString(pplugin->instance_name, plugin_instance_name.c_str()); + mjs_setString(pplugin->name, mjs_getString(plugin.name)); + mjs_setString(pplugin->instance_name, plugin_instance_name.c_str()); } // update orientation @@ -878,27 +878,27 @@ mjmBody* mjCComposite::AddCableBody(mjCModel* model, mjmBody* body, int ix, mjtN // add curvature joint if (!first || strcmp(initial.c_str(), "none")) { - mjmJoint* jnt = mjm_addJoint(body, &defjoint[mjCOMPKIND_JOINT][0].spec); - mjm_setDefault(jnt->element, mjm_getDefault(body->element)); + mjsJoint* jnt = mjs_addJoint(body, &defjoint[mjCOMPKIND_JOINT][0].spec); + mjs_setDefault(jnt->element, mjs_getDefault(body->element)); jnt->type = (first && strcmp(initial.c_str(), "free")==0) ? mjJNT_FREE : mjJNT_BALL; jnt->damping = jnt->type==mjJNT_FREE ? 0 : jnt->damping; jnt->armature = jnt->type==mjJNT_FREE ? 0 : jnt->armature; jnt->frictionloss = jnt->type==mjJNT_FREE ? 0 : jnt->frictionloss; - mjm_setString(jnt->name, this_joint); + mjs_setString(jnt->name, this_joint); } // exclude contact pair if (!last) { - mjmExclude* exclude = mjm_addExclude(&model->spec); - mjm_setString(exclude->bodyname1, std::string(this_body).c_str()); - mjm_setString(exclude->bodyname2, std::string(next_body).c_str()); + mjsExclude* exclude = mjs_addExclude(&model->spec); + mjs_setString(exclude->bodyname1, std::string(this_body).c_str()); + mjs_setString(exclude->bodyname2, std::string(next_body).c_str()); } // add site at the boundary if (last || first) { - mjmSite* site = mjm_addSite(body, &def[0].spec); - mjm_setDefault(site->element, mjm_getDefault(body->element)); - mjm_setString(site->name, txt_site); + mjsSite* site = mjs_addSite(body, &def[0].spec); + mjs_setDefault(site->element, mjs_getDefault(body->element)); + mjs_setString(site->name, txt_site); mjuu_setvec(site->pos, last ? length : 0, 0, 0); mjuu_setvec(site->quat, 1, 0, 0, 0); } @@ -908,7 +908,7 @@ mjmBody* mjCComposite::AddCableBody(mjCModel* model, mjmBody* body, int ix, mjtN // make rope -bool mjCComposite::MakeRope(mjCModel* model, mjmBody* body, char* error, int error_sz) { +bool mjCComposite::MakeRope(mjCModel* model, mjsBody* body, char* error, int error_sz) { // check dim if (dim!=1) { return comperr(error, "Rope must be one-dimensional", error_sz); @@ -917,7 +917,7 @@ bool mjCComposite::MakeRope(mjCModel* model, mjmBody* body, char* error, int err // check root body name prefix char txt[200]; mju::sprintf_arr(txt, "%sB", prefix.c_str()); - std::string body_name = mjm_getString(body->name); + std::string body_name = mjs_getString(body->name); if (std::strncmp(txt, body_name.substr(0, strlen(txt)).c_str(), mju::sizeof_arr(txt))) { mju::strcat_arr(txt, " must be the beginning of root body name"); return comperr(error, txt, error_sz); @@ -937,7 +937,7 @@ bool mjCComposite::MakeRope(mjCModel* model, mjmBody* body, char* error, int err AddRopeBody(model, body, ox, ox); // add elements: right - mjmBody* pbody = body; + mjsBody* pbody = body; for (int ix=ox; ixspec, 0); + mjsEquality* eq = mjs_addEquality(&model->spec, 0); eq->type = mjEQ_CONNECT; mju::sprintf_arr(txt, "%sB0", prefix.c_str()); mju::sprintf_arr(txt2, "%sB%d", prefix.c_str(), count[0]-1); - mjm_setString(eq->name1, txt); - mjm_setString(eq->name2, txt2); + mjs_setString(eq->name1, txt); + mjs_setString(eq->name2, txt2); mjuu_setvec(eq->data, -0.5*spacing, 0, 0); mju_copy(eq->solref, solrefsmooth, mjNREF); mju_copy(eq->solimp, solimpsmooth, mjNIMP); // remove contact between connected bodies - mjmExclude* pair = mjm_addExclude(&model->spec); - mjm_setString(pair->bodyname1, std::string(txt).c_str()); - mjm_setString(pair->bodyname2, std::string(txt2).c_str()); + mjsExclude* pair = mjs_addExclude(&model->spec); + mjs_setString(pair->bodyname1, std::string(txt).c_str()); + mjs_setString(pair->bodyname2, std::string(txt2).c_str()); } return true; @@ -975,16 +975,16 @@ bool mjCComposite::MakeRope(mjCModel* model, mjmBody* body, char* error, int err // add child body for cloth -mjmBody* mjCComposite::AddRopeBody(mjCModel* model, mjmBody* body, int ix, int ix1) { +mjsBody* mjCComposite::AddRopeBody(mjCModel* model, mjsBody* body, int ix, int ix1) { char txt[100]; bool isroot = (ix==ix1); double dx = spacing*(ix1-ix); // add child if not root if (!isroot) { - body = mjm_addBody(body, 0); + body = mjs_addBody(body, 0); mju::sprintf_arr(txt, "%sB%d", prefix.c_str(), ix1); - mjm_setString(body->name, txt); + mjs_setString(body->name, txt); // loop if (type==mjCOMPTYPE_LOOP) { @@ -1007,10 +1007,10 @@ mjmBody* mjCComposite::AddRopeBody(mjCModel* model, mjmBody* body, int ix, int i } // add geom - mjmGeom* geom = mjm_addGeom(body, &def[0].spec); - mjm_setDefault(geom->element, mjm_getDefault(body->element)); + mjsGeom* geom = mjs_addGeom(body, &def[0].spec); + mjs_setDefault(geom->element, mjs_getDefault(body->element)); mju::sprintf_arr(txt, "%sG%d", prefix.c_str(), ix1); - mjm_setString(geom->name, txt); + mjs_setString(geom->name, txt); mjuu_setvec(geom->pos, 0, 0, 0); mjuu_setvec(geom->quat, sqrt(0.5), 0, sqrt(0.5), 0); @@ -1022,10 +1022,10 @@ mjmBody* mjCComposite::AddRopeBody(mjCModel* model, mjmBody* body, int ix, int i // add main joint for (int i=0; i<2; i++) { // add joint - mjmJoint* jnt = mjm_addJoint(body, &defjoint[mjCOMPKIND_JOINT][0].spec); - mjm_setDefault(jnt->element, mjm_getDefault(body->element)); + mjsJoint* jnt = mjs_addJoint(body, &defjoint[mjCOMPKIND_JOINT][0].spec); + mjs_setDefault(jnt->element, mjs_getDefault(body->element)); mju::sprintf_arr(txt, "%sJ%d_%d", prefix.c_str(), i, ix1); - mjm_setString(jnt->name, txt); + mjs_setString(jnt->name, txt); jnt->type = mjJNT_HINGE; mjuu_setvec(jnt->pos, -0.5*dx, 0, 0); mjuu_setvec(jnt->axis, 0, 0, 0); @@ -1035,37 +1035,37 @@ mjmBody* mjCComposite::AddRopeBody(mjCModel* model, mjmBody* body, int ix, int i // add twist joint if (add[mjCOMPKIND_TWIST]) { // add joint - mjmJoint* jnt = mjm_addJoint(body, &defjoint[mjCOMPKIND_TWIST][0].spec); - mjm_setDefault(jnt->element, mjm_getDefault(body->element)); + mjsJoint* jnt = mjs_addJoint(body, &defjoint[mjCOMPKIND_TWIST][0].spec); + mjs_setDefault(jnt->element, mjs_getDefault(body->element)); mju::sprintf_arr(txt, "%sJT%d", prefix.c_str(), ix1); - mjm_setString(jnt->name, txt); + mjs_setString(jnt->name, txt); jnt->type = mjJNT_HINGE; mjuu_setvec(jnt->pos, -0.5*dx, 0, 0); mjuu_setvec(jnt->axis, 1, 0, 0); // add constraint - mjmEquality* eq = mjm_addEquality(&model->spec, &def[mjCOMPKIND_TWIST].spec); - mjm_setDefault(eq->element, &model->defaults[0]->spec); + mjsEquality* eq = mjs_addEquality(&model->spec, &def[mjCOMPKIND_TWIST].spec); + mjs_setDefault(eq->element, &model->defaults[0]->spec); eq->type = mjEQ_JOINT; - mjm_setString(eq->name1, mjm_getString(jnt->name)); + mjs_setString(eq->name1, mjs_getString(jnt->name)); } // add stretch joint if (add[mjCOMPKIND_STRETCH]) { // add joint - mjmJoint* jnt = mjm_addJoint(body, &defjoint[mjCOMPKIND_STRETCH][0].spec); - mjm_setDefault(jnt->element, mjm_getDefault(body->element)); + mjsJoint* jnt = mjs_addJoint(body, &defjoint[mjCOMPKIND_STRETCH][0].spec); + mjs_setDefault(jnt->element, mjs_getDefault(body->element)); mju::sprintf_arr(txt, "%sJS%d", prefix.c_str(), ix1); - mjm_setString(jnt->name, txt); + mjs_setString(jnt->name, txt); jnt->type = mjJNT_SLIDE; mjuu_setvec(jnt->pos, -0.5*dx, 0, 0); mjuu_setvec(jnt->axis, 1, 0, 0); // add constraint - mjmEquality* eq = mjm_addEquality(&model->spec, &def[mjCOMPKIND_STRETCH].spec); - mjm_setDefault(eq->element, &model->defaults[0]->spec); + mjsEquality* eq = mjs_addEquality(&model->spec, &def[mjCOMPKIND_STRETCH].spec); + mjs_setDefault(eq->element, &model->defaults[0]->spec); eq->type = mjEQ_JOINT; - mjm_setString(eq->name1, mjm_getString(jnt->name)); + mjs_setString(eq->name1, mjs_getString(jnt->name)); } return body; @@ -1110,7 +1110,7 @@ void mjCComposite::BoxProject(double* pos) { // make 3d box, ellipsoid or cylinder -bool mjCComposite::MakeBox(mjCModel* model, mjmBody* body, char* error, int error_sz) { +bool mjCComposite::MakeBox(mjCModel* model, mjsBody* body, char* error, int error_sz) { char txt[100]; // check dim @@ -1119,11 +1119,11 @@ bool mjCComposite::MakeBox(mjCModel* model, mjmBody* body, char* error, int erro } // center geom: two times bigger - mjmGeom* geom = mjm_addGeom(body, &def[0].spec); - mjm_setDefault(geom->element, mjm_getDefault(body->element)); + mjsGeom* geom = mjs_addGeom(body, &def[0].spec); + mjs_setDefault(geom->element, mjs_getDefault(body->element)); geom->type = mjGEOM_SPHERE; mju::sprintf_arr(txt, "%sGcenter", prefix.c_str()); - mjm_setString(geom->name, txt); + mjs_setString(geom->name, txt); mjuu_setvec(geom->pos, 0, 0, 0); geom->size[0] *= 2; geom->size[1] = 0; @@ -1143,9 +1143,9 @@ bool mjCComposite::MakeBox(mjCModel* model, mjmBody* body, char* error, int erro iy==0 || iy==count[1]-1 || iz==0 || iz==count[2]-1) { // create body - mjmBody* b = mjm_addBody(body, NULL); + mjsBody* b = mjs_addBody(body, NULL); mju::sprintf_arr(txt, "%sB%d_%d_%d", prefix.c_str(), ix, iy, iz); - mjm_setString(b->name, txt); + mjs_setString(b->name, txt); // set body position (+/- 1) b->pos[0] = 2.0*ix/(count[0]-1) - 1; @@ -1160,10 +1160,10 @@ bool mjCComposite::MakeBox(mjCModel* model, mjmBody* body, char* error, int erro mjuu_normvec(b->alt.zaxis, 3); // add geom - mjmGeom* g = mjm_addGeom(b, &def[0].spec); - mjm_setDefault(g->element, mjm_getDefault(body->element)); + mjsGeom* g = mjs_addGeom(b, &def[0].spec); + mjs_setDefault(g->element, mjs_getDefault(body->element)); mju::sprintf_arr(txt, "%sG%d_%d_%d", prefix.c_str(), ix, iy, iz); - mjm_setString(g->name, txt); + mjs_setString(g->name, txt); // offset inwards, enforce sphere or capsule if (g->type==mjGEOM_CAPSULE) { @@ -1174,22 +1174,22 @@ bool mjCComposite::MakeBox(mjCModel* model, mjmBody* body, char* error, int erro } // add slider joint - mjmJoint* jnt = mjm_addJoint(b, &defjoint[mjCOMPKIND_JOINT][0].spec); - mjm_setDefault(jnt->element, mjm_getDefault(body->element)); + mjsJoint* jnt = mjs_addJoint(b, &defjoint[mjCOMPKIND_JOINT][0].spec); + mjs_setDefault(jnt->element, mjs_getDefault(body->element)); mju::sprintf_arr(txt, "%sJ%d_%d_%d", prefix.c_str(), ix, iy, iz); - mjm_setString(jnt->name, txt); + mjs_setString(jnt->name, txt); jnt->type = mjJNT_SLIDE; mjuu_setvec(jnt->pos, 0, 0, 0); mjuu_setvec(jnt->axis, 0, 0, 1); // add fix constraint - mjmEquality* eq = mjm_addEquality(&model->spec, &def[mjCOMPKIND_JOINT].spec); - mjm_setDefault(eq->element, &model->defaults[0]->spec); + mjsEquality* eq = mjs_addEquality(&model->spec, &def[mjCOMPKIND_JOINT].spec); + mjs_setDefault(eq->element, &model->defaults[0]->spec); eq->type = mjEQ_JOINT; - mjm_setString(eq->name1, mjm_getString(jnt->name)); + mjs_setString(eq->name1, mjs_getString(jnt->name)); // add joint to tendon - ten->WrapJoint(std::string(mjm_getString(jnt->name)), 1); + ten->WrapJoint(std::string(mjs_getString(jnt->name)), 1); // add neighbor constraints for (int i=0; i<3; i++) { @@ -1203,12 +1203,12 @@ bool mjCComposite::MakeBox(mjCModel* model, mjmBody* body, char* error, int erro char txt2[200]; mju::sprintf_arr(txt2, "%sJ%d_%d_%d", prefix.c_str(), ix1, iy1, iz1); - mjmEquality* eqn = mjm_addEquality(&model->spec, 0); + mjsEquality* eqn = mjs_addEquality(&model->spec, 0); mju_copy(eqn->solref, solrefsmooth, mjNREF); mju_copy(eqn->solimp, solimpsmooth, mjNIMP); eqn->type = mjEQ_JOINT; - mjm_setString(eqn->name1, txt); - mjm_setString(eqn->name2, txt2); + mjs_setString(eqn->name1, txt); + mjs_setString(eqn->name2, txt2); } } } @@ -1217,10 +1217,10 @@ bool mjCComposite::MakeBox(mjCModel* model, mjmBody* body, char* error, int erro } // finalize fixed tendon - mjmEquality* eqt = mjm_addEquality(&model->spec, &def[mjCOMPKIND_TENDON].spec); - mjm_setDefault(eqt->element, &model->defaults[0]->spec); + mjsEquality* eqt = mjs_addEquality(&model->spec, &def[mjCOMPKIND_TENDON].spec); + mjs_setDefault(eqt->element, &model->defaults[0]->spec); eqt->type = mjEQ_TENDON; - mjm_setString(eqt->name1, ten->name.c_str()); + mjs_setString(eqt->name1, ten->name.c_str()); // skin if (skin) { @@ -1253,10 +1253,10 @@ void mjCComposite::MakeShear(mjCModel* model) { ten->name = txt; // equality constraint - mjmEquality* eq = mjm_addEquality(&model->spec, &def[mjCOMPKIND_SHEAR].spec); - mjm_setDefault(eq->element, &model->defaults[0]->spec); + mjsEquality* eq = mjs_addEquality(&model->spec, &def[mjCOMPKIND_SHEAR].spec); + mjs_setDefault(eq->element, &model->defaults[0]->spec); eq->type = mjEQ_TENDON; - mjm_setString(eq->name1, txt); + mjs_setString(eq->name1, txt); } } } @@ -1264,18 +1264,18 @@ void mjCComposite::MakeShear(mjCModel* model) { // copy local vectors to skin -void mjCComposite::CopyIntoSkin(mjmSkin* skin) { - mjm_setInt(skin->face, face.data(), face.size()); - mjm_setFloat(skin->vert, vert.data(), vert.size()); - mjm_setFloat(skin->bindpos, bindpos.data(), bindpos.size()); - mjm_setFloat(skin->bindquat, bindquat.data(), bindquat.size()); - mjm_setFloat(skin->texcoord, texcoord.data(), texcoord.size()); +void mjCComposite::CopyIntoSkin(mjsSkin* skin) { + mjs_setInt(skin->face, face.data(), face.size()); + mjs_setFloat(skin->vert, vert.data(), vert.size()); + mjs_setFloat(skin->bindpos, bindpos.data(), bindpos.size()); + mjs_setFloat(skin->bindquat, bindquat.data(), bindquat.size()); + mjs_setFloat(skin->texcoord, texcoord.data(), texcoord.size()); for (int i=0; ivertid, vertid[i].data(), vertid[i].size()); + mjs_appendIntVec(skin->vertid, vertid[i].data(), vertid[i].size()); } for (int i=0; i< vertweight.size(); i++) { - mjm_appendFloatVec(skin->vertweight, vertweight[i].data(), vertweight[i].size()); + mjs_appendFloatVec(skin->vertweight, vertweight[i].data(), vertweight[i].size()); } face.clear(); @@ -1295,10 +1295,10 @@ void mjCComposite::MakeSkin2(mjCModel* model, mjtNum inflate) { int N = count[0]*count[1]; // add skin, set name and material - mjmSkin* skin = mjm_addSkin(&model->spec); + mjsSkin* skin = mjs_addSkin(&model->spec); mju::sprintf_arr(txt, "%sSkin", prefix.c_str()); - mjm_setString(skin->name, txt); - mjm_setString(skin->material, skinmaterial.c_str()); + mjs_setString(skin->name, txt); + mjs_setString(skin->material, skinmaterial.c_str()); mjuu_copyvec(skin->rgba, skinrgba, 4); skin->inflate = inflate; skin->group = skingroup; @@ -1316,7 +1316,7 @@ void mjCComposite::MakeSkin2(mjCModel* model, mjtNum inflate) { vert.push_back(0); mju::sprintf_arr(txt, "%sB%d", prefix.c_str(), i); - mjm_appendString(skin->bodyname, txt); + mjs_appendString(skin->bodyname, txt); bindpos.push_back(0); bindpos.push_back(0); bindpos.push_back(0); @@ -1426,7 +1426,7 @@ void mjCComposite::MakeSkin2(mjCModel* model, mjtNum inflate) { // add bones in 2D -void mjCComposite::MakeClothBones(mjCModel* model, mjmSkin* skin) { +void mjCComposite::MakeClothBones(mjCModel* model, mjsSkin* skin) { char txt[100]; int N = count[0]*count[1]; @@ -1441,7 +1441,7 @@ void mjCComposite::MakeClothBones(mjCModel* model, mjmSkin* skin) { } // bind pose - mjm_appendString(skin->bodyname, txt); + mjs_appendString(skin->bodyname, txt); bindpos.push_back(0); bindpos.push_back(0); bindpos.push_back(0); @@ -1459,7 +1459,7 @@ void mjCComposite::MakeClothBones(mjCModel* model, mjmSkin* skin) { -void mjCComposite::MakeClothBonesSubgrid(mjCModel* model, mjmSkin* skin) { +void mjCComposite::MakeClothBonesSubgrid(mjCModel* model, mjsSkin* skin) { char txt[100]; // populate bones @@ -1473,7 +1473,7 @@ void mjCComposite::MakeClothBonesSubgrid(mjCModel* model, mjmSkin* skin) { } // bind pose - mjm_appendString(skin->bodyname, txt); + mjs_appendString(skin->bodyname, txt); bindpos.push_back(ix*spacing); bindpos.push_back(iy*spacing); bindpos.push_back(0); @@ -1492,7 +1492,7 @@ void mjCComposite::MakeClothBonesSubgrid(mjCModel* model, mjmSkin* skin) { // add bones to 1D -void mjCComposite::MakeCableBones(mjCModel* model, mjmSkin* skin) { +void mjCComposite::MakeCableBones(mjCModel* model, mjsSkin* skin) { char this_body[100]; int N = count[0]*count[1]; @@ -1510,14 +1510,14 @@ void mjCComposite::MakeCableBones(mjCModel* model, mjmSkin* skin) { // bind pose if (iy==0) { - mjm_appendString(skin->bodyname, this_body); + mjs_appendString(skin->bodyname, this_body); bindpos.push_back((ix==count[0]-1) ? -2*def[0].spec.geom->size[0] : 0); bindpos.push_back(-def[0].spec.geom->size[1]); bindpos.push_back(0); bindquat.push_back(1); bindquat.push_back(0); bindquat.push_back(0); bindquat.push_back(0); } else { - mjm_appendString(skin->bodyname, this_body); + mjs_appendString(skin->bodyname, this_body); bindpos.push_back((ix==count[0]-1) ? -2*def[0].spec.geom->size[0] : 0); bindpos.push_back(def[0].spec.geom->size[1]); bindpos.push_back(0); @@ -1534,7 +1534,7 @@ void mjCComposite::MakeCableBones(mjCModel* model, mjmSkin* skin) { -void mjCComposite::MakeCableBonesSubgrid(mjCModel* model, mjmSkin* skin) { +void mjCComposite::MakeCableBonesSubgrid(mjCModel* model, mjsSkin* skin) { // populate bones for (int ix=0; ixbodyname, txt); + mjs_appendString(skin->bodyname, txt); bindquat.push_back(1); bindquat.push_back(0); bindquat.push_back(0); @@ -1888,10 +1888,10 @@ void mjCComposite::MakeSkin2Subgrid(mjCModel* model, mjtNum inflate) { // add skin, set name and material char txt[100]; - mjmSkin* skin = mjm_addSkin(&model->spec); + mjsSkin* skin = mjs_addSkin(&model->spec); mju::sprintf_arr(txt, "%sSkin", prefix.c_str()); - mjm_setString(skin->name, txt); - mjm_setString(skin->material, skinmaterial.c_str()); + mjs_setString(skin->name, txt); + mjs_setString(skin->material, skinmaterial.c_str()); mjuu_copyvec(skin->rgba, skinrgba, 4); skin->inflate = inflate; skin->group = skingroup; @@ -2043,10 +2043,10 @@ void mjCComposite::MakeSkin3(mjCModel* model) { mju::sprintf_arr(cnt2, "%d", count[2]-1); // add skin, set name and material - mjmSkin* skin = mjm_addSkin(&model->spec); + mjsSkin* skin = mjs_addSkin(&model->spec); mju::sprintf_arr(txt, "%sSkin", prefix.c_str()); - mjm_setString(skin->name, txt); - mjm_setString(skin->material, skinmaterial.c_str()); + mjs_setString(skin->name, txt); + mjs_setString(skin->material, skinmaterial.c_str()); mjuu_copyvec(skin->rgba, skinrgba, 4); skin->inflate = skininflate; skin->group = skingroup; @@ -2191,7 +2191,7 @@ void mjCComposite::MakeSkin3(mjCModel* model) { // make one face of 3D skin, box -void mjCComposite::MakeSkin3Box(mjmSkin* skin, int c0, int c1, int side, +void mjCComposite::MakeSkin3Box(mjsSkin* skin, int c0, int c1, int side, int& vcnt, const char* format) { char txt[100]; @@ -2224,7 +2224,7 @@ void mjCComposite::MakeSkin3Box(mjmSkin* skin, int c0, int c1, int side, mju::sprintf_arr(txt, format, prefix.c_str(), i0, i1); // bind pose: origin - mjm_appendString(skin->bodyname, txt); + mjs_appendString(skin->bodyname, txt); bindpos.push_back(0); bindpos.push_back(0); bindpos.push_back(0); @@ -2246,7 +2246,7 @@ void mjCComposite::MakeSkin3Box(mjmSkin* skin, int c0, int c1, int side, // make one face of 3D skin, smooth -void mjCComposite::MakeSkin3Smooth(mjmSkin* skin, int c0, int c1, int side, +void mjCComposite::MakeSkin3Smooth(mjsSkin* skin, int c0, int c1, int side, const std::map& vmap, const char* format) { char txt00[100], txt01[100], txt10[100], txt11[100]; @@ -2281,7 +2281,7 @@ void mjCComposite::MakeSkin3Smooth(mjmSkin* skin, int c0, int c1, int side, } // bind pose: origin - mjm_appendString(skin->bodyname, txt00); + mjs_appendString(skin->bodyname, txt00); bindpos.push_back(0); bindpos.push_back(0); bindpos.push_back(0); diff --git a/src/user/user_composite.h b/src/user/user_composite.h index 6b30e2fa..bbc49a72 100644 --- a/src/user/user_composite.h +++ b/src/user/user_composite.h @@ -69,25 +69,25 @@ class mjCComposite { bool AddDefaultJoint(char* error = NULL, int error_sz = 0); void AdjustSoft(mjtNum* solref, mjtNum* solimp, int level); - bool Make(mjSpec* spec, mjmBody* body, char* error, int error_sz); + bool Make(mjSpec* spec, mjsBody* body, char* error, int error_sz); - bool MakeParticle(mjCModel* model, mjmBody* body, char* error, int error_sz); - bool MakeGrid(mjCModel* model, mjmBody* body, char* error, int error_sz); - bool MakeRope(mjCModel* model, mjmBody* body, char* error, int error_sz); - bool MakeCable(mjCModel* model, mjmBody* body, char* error, int error_sz); - bool MakeBox(mjCModel* model, mjmBody* body, char* error, int error_sz); + bool MakeParticle(mjCModel* model, mjsBody* body, char* error, int error_sz); + bool MakeGrid(mjCModel* model, mjsBody* body, char* error, int error_sz); + bool MakeRope(mjCModel* model, mjsBody* body, char* error, int error_sz); + bool MakeCable(mjCModel* model, mjsBody* body, char* error, int error_sz); + bool MakeBox(mjCModel* model, mjsBody* body, char* error, int error_sz); void MakeShear(mjCModel* model); void MakeSkin2(mjCModel* model, mjtNum inflate); void MakeSkin2Subgrid(mjCModel* model, mjtNum inflate); - void MakeClothBones(mjCModel* model, mjmSkin* skin); - void MakeClothBonesSubgrid(mjCModel* model, mjmSkin* skin); - void MakeCableBones(mjCModel* model, mjmSkin* skin); - void MakeCableBonesSubgrid(mjCModel* model, mjmSkin* skin); + void MakeClothBones(mjCModel* model, mjsSkin* skin); + void MakeClothBonesSubgrid(mjCModel* model, mjsSkin* skin); + void MakeCableBones(mjCModel* model, mjsSkin* skin); + void MakeCableBonesSubgrid(mjCModel* model, mjsSkin* skin); void MakeSkin3(mjCModel* model); - void MakeSkin3Box(mjmSkin* skin, int c0, int c1, int side, int& vcnt, const char* format); - void MakeSkin3Smooth(mjmSkin* skin, int c0, int c1, int side, + void MakeSkin3Box(mjsSkin* skin, int c0, int c1, int side, int& vcnt, const char* format); + void MakeSkin3Smooth(mjsSkin* skin, int c0, int c1, int side, const std::map& vmap, const char* format); void BoxProject(double* pos); @@ -116,7 +116,7 @@ class mjCComposite { // plugin support std::string plugin_name; std::string plugin_instance_name; - mjmPlugin plugin; + mjsPlugin plugin; // skin bool skin; // generate skin @@ -136,11 +136,11 @@ class mjCComposite { int dim; // dimensionality private: - mjmBody* AddRopeBody(mjCModel* model, mjmBody* body, int ix, int ix1); - mjmBody* AddCableBody(mjCModel* model, mjmBody* body, int ix, mjtNum normal[3], mjtNum prev_quat[4]); + mjsBody* AddRopeBody(mjCModel* model, mjsBody* body, int ix, int ix1); + mjsBody* AddCableBody(mjCModel* model, mjsBody* body, int ix, mjtNum normal[3], mjtNum prev_quat[4]); // temporary skin vectors - void CopyIntoSkin(mjmSkin* skin); + void CopyIntoSkin(mjsSkin* skin); std::vector face; std::vector vert; std::vector bindpos; diff --git a/src/user/user_flexcomp.cc b/src/user/user_flexcomp.cc index 0686065d..41e031e6 100644 --- a/src/user/user_flexcomp.cc +++ b/src/user/user_flexcomp.cc @@ -72,7 +72,7 @@ mjCFlexcomp::mjCFlexcomp(void) { rigid = false; centered = false; - mjm_defaultPlugin(plugin); + mjs_defaultPlugin(plugin); plugin_name = ""; plugin_instance_name = ""; plugin.name = (mjString)&plugin_name; @@ -82,9 +82,9 @@ mjCFlexcomp::mjCFlexcomp(void) { // make flexcomp object -bool mjCFlexcomp::Make(mjSpec* spec, mjmBody* body, char* error, int error_sz) { +bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) { mjCModel* model = (mjCModel*)spec->element; - mjmFlex* dflex = def.spec.flex; + mjsFlex* dflex = def.spec.flex; int dim = dflex->dim; bool radial = (type==mjFCOMPTYPE_BOX || type==mjFCOMPTYPE_CYLINDER || @@ -94,7 +94,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjmBody* body, char* error, int error_sz) { type==mjFCOMPTYPE_GMSH); // check parent body name - if (std::string(mjm_getString(body->name)).empty()) { + if (std::string(mjs_getString(body->name)).empty()) { return comperr(error, "Parent body must have name", error_sz); } @@ -381,7 +381,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjmBody* body, char* error, int error_sz) { // create flex, copy parameters mjCFlex* flex = model->AddFlex(); - mjmFlex* pf = &flex->spec; + mjsFlex* pf = &flex->spec; int id = flex->id; *flex = def.flex; @@ -389,13 +389,13 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjmBody* body, char* error, int error_sz) { flex->model = model; flex->id = id; - mjm_setString(pf->name, name.c_str()); - mjm_setInt(pf->elem, element.data(), element.size()); - mjm_setFloat(pf->texcoord, texcoord.data(), texcoord.size()); + mjs_setString(pf->name, name.c_str()); + mjs_setInt(pf->elem, element.data(), element.size()); + mjs_setFloat(pf->texcoord, texcoord.data(), texcoord.size()); // rigid: set parent name, nothing else to do if (rigid) { - mjm_appendString(pf->vertbody, mjm_getString(body->name)); + mjs_appendString(pf->vertbody, mjs_getString(body->name)); return true; } @@ -418,22 +418,22 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjmBody* body, char* error, int error_sz) { // pinned: parent body if (pinned[i]) { - mjm_appendString(pf->vertbody, mjm_getString(body->name)); + mjs_appendString(pf->vertbody, mjs_getString(body->name)); // add plugin if (plugin.active) { - mjmPlugin* pplugin = &body->plugin; + mjsPlugin* pplugin = &body->plugin; pplugin->active = true; pplugin->instance = (mjElement)plugin.instance; - mjm_setString(pplugin->name, mjm_getString(plugin.name)); - mjm_setString(pplugin->instance_name, plugin_instance_name.c_str()); + mjs_setString(pplugin->name, mjs_getString(plugin.name)); + mjs_setString(pplugin->instance_name, plugin_instance_name.c_str()); } } // not pinned: new body else { // add new body at vertex coordinates - mjmBody* pb = mjm_addBody(body, 0); + mjsBody* pb = mjs_addBody(body, 0); // set frame and inertial pb->pos[0] = point[3*i]; @@ -448,7 +448,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjmBody* body, char* error, int error_sz) { // add radial slider if (radial) { - mjmJoint* jnt = mjm_addJoint(pb, 0); + mjsJoint* jnt = mjs_addJoint(pb, 0); // set properties jnt->type = mjJNT_SLIDE; @@ -461,7 +461,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjmBody* body, char* error, int error_sz) { else { for (int j=0; j<3; j++) { // add joint to body - mjmJoint* jnt = mjm_addJoint(pb, 0); + mjsJoint* jnt = mjs_addJoint(pb, 0); // set properties jnt->type = mjJNT_SLIDE; @@ -474,8 +474,8 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjmBody* body, char* error, int error_sz) { // construct body name, add to vertbody char txt[100]; mju::sprintf_arr(txt, "%s_%d", name.c_str(), i); - mjm_setString(pb->name, txt); - mjm_appendString(pf->vertbody, mjm_getString(pb->name)); + mjs_setString(pb->name, txt); + mjs_appendString(pf->vertbody, mjs_getString(pb->name)); // clear flex vertex coordinates if allocated if (!centered) { @@ -486,26 +486,26 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjmBody* body, char* error, int error_sz) { // add plugin if (plugin.active) { - mjmPlugin* pplugin = &pb->plugin; + mjsPlugin* pplugin = &pb->plugin; pplugin->active = true; pplugin->instance = (mjElement)plugin.instance; - mjm_setString(pplugin->name, mjm_getString(plugin.name)); - mjm_setString(pplugin->instance_name, plugin_instance_name.c_str()); + mjs_setString(pplugin->name, mjs_getString(plugin.name)); + mjs_setString(pplugin->instance_name, plugin_instance_name.c_str()); } } } if (!centered) { - mjm_setDouble(pf->vert, point.data(), point.size()); + mjs_setDouble(pf->vert, point.data(), point.size()); } // create edge equality constraint if (equality) { - mjmEquality* pe = mjm_addEquality(&model->spec, &def.spec); - mjm_setDefault(pe->element, &model->defaults[0]->spec); + mjsEquality* pe = mjs_addEquality(&model->spec, &def.spec); + mjs_setDefault(pe->element, &model->defaults[0]->spec); pe->type = mjEQ_FLEX; pe->active = true; - mjm_setString(pe->name1, name.c_str()); + mjs_setString(pe->name1, name.c_str()); } return true; @@ -885,8 +885,8 @@ bool mjCFlexcomp::MakeMesh(mjCModel* model, char* error, int error_sz) { } // load resource - string filename = mjuu_makefullname(mjm_getString(model->spec.modelfiledir), - mjm_getString(model->spec.meshdir), file); + string filename = mjuu_makefullname(mjs_getString(model->spec.modelfiledir), + mjs_getString(model->spec.meshdir), file); mjResource* resource = nullptr; try { @@ -992,8 +992,8 @@ bool mjCFlexcomp::MakeGMSH(mjCModel* model, char* error, int error_sz) { } // open resource - string filename = mjuu_makefullname(mjm_getString(model->spec.modelfiledir), - mjm_getString(model->spec.meshdir), file); + string filename = mjuu_makefullname(mjs_getString(model->spec.modelfiledir), + mjs_getString(model->spec.meshdir), file); mjResource* resource = nullptr; try { diff --git a/src/user/user_flexcomp.h b/src/user/user_flexcomp.h index 54c44a4b..8e6b4340 100644 --- a/src/user/user_flexcomp.h +++ b/src/user/user_flexcomp.h @@ -42,7 +42,7 @@ typedef enum _mjtFcompType { class mjCFlexcomp { public: mjCFlexcomp(void); - bool Make(mjSpec* spec, mjmBody* body, char* error, int error_sz); + bool Make(mjSpec* spec, mjsBody* body, char* error, int error_sz); bool MakeGrid(char* error, int error_sz); bool MakeBox(char* error, int error_sz); @@ -93,7 +93,7 @@ class mjCFlexcomp { // plugin support std::string plugin_name; std::string plugin_instance_name; - mjmPlugin plugin; + mjsPlugin plugin; }; #endif // MUJOCO_SRC_USER_USER_FLEXCOMP_H_ diff --git a/src/user/user_init.cc b/src/user/user_init.cc index 77716bdb..0e85848e 100644 --- a/src/user/user_init.cc +++ b/src/user/user_init.cc @@ -22,7 +22,7 @@ // default model attributes -void mjm_defaultSpec(mjSpec& model) { +void mjs_defaultSpec(mjSpec& model) { memset(&model, 0, sizeof(mjSpec)); // default statistics @@ -76,8 +76,8 @@ void mjm_defaultSpec(mjSpec& model) { // default body attributes -void mjm_defaultBody(mjmBody& body) { - memset(&body, 0, sizeof(mjmBody)); +void mjs_defaultBody(mjsBody& body) { + memset(&body, 0, sizeof(mjsBody)); // body frame body.pos[0] = mjNAN; @@ -94,8 +94,8 @@ void mjm_defaultBody(mjmBody& body) { // default frame attributes -void mjm_defaultFrame(mjmFrame& frame) { - memset(&frame, 0, sizeof(mjmFrame)); +void mjs_defaultFrame(mjsFrame& frame) { + memset(&frame, 0, sizeof(mjsFrame)); mju_zero3(frame.pos); mjuu_setvec(frame.quat, 1, 0, 0, 0); frame.alt.axisangle[0] = frame.alt.xyaxes[0] = frame.alt.zaxis[0] = frame.alt.euler[0] = mjNAN; @@ -104,8 +104,8 @@ void mjm_defaultFrame(mjmFrame& frame) { // default joint attributes -void mjm_defaultJoint(mjmJoint& joint) { - memset(&joint, 0, sizeof(mjmJoint)); +void mjs_defaultJoint(mjsJoint& joint) { + memset(&joint, 0, sizeof(mjsJoint)); joint.type = mjJNT_HINGE; joint.axis[2] = 1; @@ -119,8 +119,8 @@ void mjm_defaultJoint(mjmJoint& joint) { // default geom attributes -void mjm_defaultGeom(mjmGeom& geom) { - memset(&geom, 0, sizeof(mjmGeom)); +void mjs_defaultGeom(mjsGeom& geom) { + memset(&geom, 0, sizeof(mjsGeom)); // type geom.type = mjGEOM_SPHERE; @@ -163,9 +163,9 @@ void mjm_defaultGeom(mjmGeom& geom) { // default site attributes -void mjm_defaultSite(mjmSite& site) { +void mjs_defaultSite(mjsSite& site) { // set everything to 0 / false / NULL - memset(&site, 0, sizeof(mjmSite)); + memset(&site, 0, sizeof(mjsSite)); // type site.type = mjGEOM_SPHERE; @@ -184,8 +184,8 @@ void mjm_defaultSite(mjmSite& site) { // default cam attributes -void mjm_defaultCamera(mjmCamera& cam) { - memset(&cam, 0, sizeof(mjmCamera)); +void mjs_defaultCamera(mjsCamera& cam) { + memset(&cam, 0, sizeof(mjsCamera)); // type cam.mode = mjCAMLIGHT_FIXED; @@ -203,8 +203,8 @@ void mjm_defaultCamera(mjmCamera& cam) { // default light attributes -void mjm_defaultLight(mjmLight& light) { - memset(&light, 0, sizeof(mjmLight)); +void mjs_defaultLight(mjsLight& light) { + memset(&light, 0, sizeof(mjsLight)); // mode light.mode = mjCAMLIGHT_FIXED; @@ -223,8 +223,8 @@ void mjm_defaultLight(mjmLight& light) { // default flex attributes -void mjm_defaultFlex(mjmFlex& flex) { - memset(&flex, 0, sizeof(mjmFlex)); +void mjs_defaultFlex(mjsFlex& flex) { + memset(&flex, 0, sizeof(mjsFlex)); // set contact defaults flex.contype = 1; @@ -247,8 +247,8 @@ void mjm_defaultFlex(mjmFlex& flex) { // default mesh attributes -void mjm_defaultMesh(mjmMesh& mesh) { - memset(&mesh, 0, sizeof(mjmMesh)); +void mjs_defaultMesh(mjsMesh& mesh) { + memset(&mesh, 0, sizeof(mjsMesh)); mjuu_setvec(mesh.refpos, 0, 0, 0); mjuu_setvec(mesh.refquat, 1, 0, 0, 0); mjuu_setvec(mesh.scale, 1, 1, 1); @@ -258,15 +258,15 @@ void mjm_defaultMesh(mjmMesh& mesh) { // default height field attributes -void mjm_defaultHField(mjmHField& hfield) { - memset(&hfield, 0, sizeof(mjmHField)); +void mjs_defaultHField(mjsHField& hfield) { + memset(&hfield, 0, sizeof(mjsHField)); } // default skin attributes -void mjm_defaultSkin(mjmSkin& skin) { - memset(&skin, 0, sizeof(mjmSkin)); +void mjs_defaultSkin(mjsSkin& skin) { + memset(&skin, 0, sizeof(mjsSkin)); skin.rgba[0] = skin.rgba[1] = skin.rgba[2] = 0.5f; skin.rgba[3] = 1.0f; skin.inflate = 0; @@ -276,8 +276,8 @@ void mjm_defaultSkin(mjmSkin& skin) { // default texture attributes -void mjm_defaultTexture(mjmTexture& texture) { - memset(&texture, 0, sizeof(mjmTexture)); +void mjs_defaultTexture(mjsTexture& texture) { + memset(&texture, 0, sizeof(mjsTexture)); texture.type = mjTEXTURE_CUBE; mjuu_setvec(texture.rgb1, 0.8, 0.8, 0.8); mjuu_setvec(texture.rgb2, 0.5, 0.5, 0.5); @@ -290,8 +290,8 @@ void mjm_defaultTexture(mjmTexture& texture) { // default material attributes -void mjm_defaultMaterial(mjmMaterial& material) { - memset(&material, 0, sizeof(mjmMaterial)); +void mjs_defaultMaterial(mjsMaterial& material) { + memset(&material, 0, sizeof(mjsMaterial)); material.texuniform = false; material.texrepeat[0] = material.texrepeat[1] = 1; material.emission = 0; @@ -304,8 +304,8 @@ void mjm_defaultMaterial(mjmMaterial& material) { // default pair attributes -void mjm_defaultPair(mjmPair& pair) { - memset(&pair, 0, sizeof(mjmPair)); +void mjs_defaultPair(mjsPair& pair) { + memset(&pair, 0, sizeof(mjsPair)); pair.condim = 3; mj_defaultSolRefImp(pair.solref, pair.solimp); pair.friction[0] = 1; @@ -318,8 +318,8 @@ void mjm_defaultPair(mjmPair& pair) { // default equality attributes -void mjm_defaultEquality(mjmEquality& equality) { - memset(&equality, 0, sizeof(mjmEquality)); +void mjs_defaultEquality(mjsEquality& equality) { + memset(&equality, 0, sizeof(mjsEquality)); equality.type = mjEQ_CONNECT; equality.active = 1; mj_defaultSolRefImp(equality.solref, equality.solimp); @@ -330,8 +330,8 @@ void mjm_defaultEquality(mjmEquality& equality) { // default tendon attributes -void mjm_defaultTendon(mjmTendon& tendon) { - memset(&tendon, 0, sizeof(mjmTendon)); +void mjs_defaultTendon(mjsTendon& tendon) { + memset(&tendon, 0, sizeof(mjsTendon)); tendon.limited = mjLIMITED_AUTO; tendon.springlength[0] = tendon.springlength[1] = -1; mj_defaultSolRefImp(tendon.solref_limit, tendon.solimp_limit); @@ -344,8 +344,8 @@ void mjm_defaultTendon(mjmTendon& tendon) { // default actuator attributes -void mjm_defaultActuator(mjmActuator& actuator) { - memset(&actuator, 0, sizeof(mjmActuator)); +void mjs_defaultActuator(mjsActuator& actuator) { + memset(&actuator, 0, sizeof(mjsActuator)); // gain, bias actuator.gaintype = mjGAIN_FIXED; @@ -370,8 +370,8 @@ void mjm_defaultActuator(mjmActuator& actuator) { // default sensor attributes -void mjm_defaultSensor(mjmSensor& sensor) { - memset(&sensor, 0, sizeof(mjmSensor)); +void mjs_defaultSensor(mjsSensor& sensor) { + memset(&sensor, 0, sizeof(mjsSensor)); sensor.type = mjSENS_TOUCH; sensor.datatype = mjDATATYPE_REAL; sensor.needstage = mjSTAGE_ACC; @@ -380,36 +380,36 @@ void mjm_defaultSensor(mjmSensor& sensor) { // Default numeric attributes. -void mjm_defaultNumeric(mjmNumeric& numeric) { - memset(&numeric, 0, sizeof(mjmNumeric)); +void mjs_defaultNumeric(mjsNumeric& numeric) { + memset(&numeric, 0, sizeof(mjsNumeric)); } // Default text attributes. -void mjm_defaultText(mjmText& text) { - memset(&text, 0, sizeof(mjmText)); +void mjs_defaultText(mjsText& text) { + memset(&text, 0, sizeof(mjsText)); } // Default tuple attributes. -void mjm_defaultTuple(mjmTuple& tuple) { - memset(&tuple, 0, sizeof(mjmTuple)); +void mjs_defaultTuple(mjsTuple& tuple) { + memset(&tuple, 0, sizeof(mjsTuple)); } // Default keyframe attributes. -void mjm_defaultKey(mjmKey& key) { - memset(&key, 0, sizeof(mjmKey)); +void mjs_defaultKey(mjsKey& key) { + memset(&key, 0, sizeof(mjsKey)); } // default plugin attributes -void mjm_defaultPlugin(mjmPlugin& plugin) { - memset(&plugin, 0, sizeof(mjmPlugin)); +void mjs_defaultPlugin(mjsPlugin& plugin) { + memset(&plugin, 0, sizeof(mjsPlugin)); plugin.plugin_slot = -1; } diff --git a/src/user/user_mesh.cc b/src/user/user_mesh.cc index c6c5d9de..71357f45 100644 --- a/src/user/user_mesh.cc +++ b/src/user/user_mesh.cc @@ -130,7 +130,7 @@ static void ReadFromBuffer(T* dst, const char* src) { //------------------ class mjCMesh implementation -------------------------------------------------- mjCMesh::mjCMesh(mjCModel* _model, mjCDef* _def) { - mjm_defaultMesh(spec); + mjs_defaultMesh(spec); // clear internal variables mjuu_setvec(pos_surface_, 0, 0, 0); @@ -195,7 +195,7 @@ mjCMesh& mjCMesh::operator=(const mjCMesh& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); if (other.vert_) { size_t nvert = 3*other.nvert_*sizeof(float); this->vert_ = (float*)mju_malloc(nvert); @@ -282,7 +282,7 @@ void mjCMesh::PointToLocal() { void mjCMesh::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; file_ = spec_file_; content_type_ = spec_content_type_; uservert_ = spec_uservert_; @@ -2054,7 +2054,7 @@ void mjCMesh::MakeCenter(void) { // constructor mjCSkin::mjCSkin(mjCModel* _model) { - mjm_defaultSkin(spec); + mjs_defaultSkin(spec); // set model pointer model = _model; @@ -2093,7 +2093,7 @@ mjCSkin& mjCSkin::operator=(const mjCSkin& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); } PointToLocal(); return *this; @@ -2129,7 +2129,7 @@ void mjCSkin::NameSpace(const mjCModel* m) { void mjCSkin::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; file_ = spec_file_; material_ = spec_material_; vert_ = spec_vert_; @@ -2478,7 +2478,7 @@ constexpr int eledge[3][6][2] = {{{ 0, 1}, {-1, -1}, {-1, -1}, // constructor mjCFlex::mjCFlex(mjCModel* _model) { - mjm_defaultFlex(spec); + mjs_defaultFlex(spec); // set model model = _model; @@ -2505,7 +2505,7 @@ mjCFlex& mjCFlex::operator=(const mjCFlex& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); } PointToLocal(); return *this; @@ -2535,7 +2535,7 @@ void mjCFlex::NameSpace(const mjCModel* m) { void mjCFlex::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; spec.info = (mjString)&info; material_ = spec_material_; vertbody_ = spec_vertbody_; diff --git a/src/user/user_model.cc b/src/user/user_model.cc index 0cd073f6..d8a72c50 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -83,7 +83,7 @@ static void copyvec(T1* dest, T2* src, int n) { // constructor mjCModel::mjCModel() { - mjm_defaultSpec(spec); + mjs_defaultSpec(spec); spec_comment_.clear(); spec_modelfiledir_.clear(); spec_meshdir_.clear(); diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index 8e2a1d78..79008f69 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -432,18 +432,18 @@ mjCDef::mjCDef(void) { name.clear(); parentid = -1; childid.clear(); - mjm_defaultJoint(joint.spec); - mjm_defaultGeom(geom.spec); - mjm_defaultSite(site.spec); - mjm_defaultCamera(camera.spec); - mjm_defaultLight(light.spec); - mjm_defaultFlex(flex.spec); - mjm_defaultMesh(mesh.spec); - mjm_defaultMaterial(material.spec); - mjm_defaultPair(pair.spec); - mjm_defaultEquality(equality.spec); - mjm_defaultTendon(tendon.spec); - mjm_defaultActuator(actuator.spec); + mjs_defaultJoint(joint.spec); + mjs_defaultGeom(geom.spec); + mjs_defaultSite(site.spec); + mjs_defaultCamera(camera.spec); + mjs_defaultLight(light.spec); + mjs_defaultFlex(flex.spec); + mjs_defaultMesh(mesh.spec); + mjs_defaultMaterial(material.spec); + mjs_defaultPair(pair.spec); + mjs_defaultEquality(equality.spec); + mjs_defaultTendon(tendon.spec); + mjs_defaultActuator(actuator.spec); // make sure all the pointers are local PointToLocal(); @@ -626,7 +626,7 @@ mjCBody::mjCBody(mjCModel* _model) { // set model pointer model = _model; - mjm_defaultBody(spec); + mjs_defaultBody(spec); parentid = -1; weldid = -1; dofnum = 0; @@ -668,7 +668,7 @@ mjCBody& mjCBody::operator=(const mjCBody& other) { if (this != &other) { spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); std::map fmap; mjCFrame *np = nullptr; bodies.clear(); @@ -751,7 +751,7 @@ void mjCBody::PointToLocal() { void mjCBody::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; userdata_ = spec_userdata_; userdata = (mjDoubleVec)&userdata_; mju_copy4(alt_.axisangle, alt.axisangle); @@ -1367,7 +1367,7 @@ void mjCBody::Compile(void) { // initialize frame mjCFrame::mjCFrame(mjCModel* _model, mjCFrame* _frame) { - mjm_defaultFrame(spec); + mjs_defaultFrame(spec); compiled = false; model = _model; body = NULL; @@ -1388,7 +1388,7 @@ mjCFrame& mjCFrame::operator=(const mjCFrame& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); } PointToLocal(); return *this; @@ -1429,7 +1429,7 @@ void mjCFrame::PointToLocal() { void mjCFrame::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; mju_copy3(pos, spec.pos); mju_copy4(quat, spec.quat); mju_copy4(alt_.axisangle, alt.axisangle); @@ -1467,7 +1467,7 @@ void mjCFrame::Compile() { // initialize default joint mjCJoint::mjCJoint(mjCModel* _model, mjCDef* _def) { - mjm_defaultJoint(spec); + mjs_defaultJoint(spec); // clear internal variables spec_userdata_.clear(); @@ -1501,7 +1501,7 @@ mjCJoint& mjCJoint::operator=(const mjCJoint& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); } PointToLocal(); return *this; @@ -1525,7 +1525,7 @@ void mjCJoint::PointToLocal() { void mjCJoint::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; userdata_ = spec_userdata_; userdata = (mjDoubleVec)&spec_userdata_; } @@ -1664,7 +1664,7 @@ int mjCJoint::Compile(void) { // initialize default geom mjCGeom::mjCGeom(mjCModel* _model, mjCDef* _def) { - mjm_defaultGeom(spec); + mjs_defaultGeom(spec); mass_ = 0; body = 0; @@ -1712,7 +1712,7 @@ mjCGeom& mjCGeom::operator=(const mjCGeom& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); } PointToLocal(); return *this; @@ -1737,7 +1737,7 @@ void mjCGeom::PointToLocal(void) { void mjCGeom::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; userdata_ = spec_userdata_; hfieldname_ = spec_hfieldname_; meshname_ = spec_meshname_; @@ -2294,7 +2294,7 @@ void mjCGeom::Compile(void) { // initialize default site mjCSite::mjCSite(mjCModel* _model, mjCDef* _def) { - mjm_defaultSite(spec); + mjs_defaultSite(spec); // clear internal variables body = 0; @@ -2330,7 +2330,7 @@ mjCSite& mjCSite::operator=(const mjCSite& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); } PointToLocal(); return *this; @@ -2350,7 +2350,7 @@ void mjCSite::PointToLocal() { void mjCSite::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; userdata_ = spec_userdata_; material_ = spec_material_; userdata = (mjDoubleVec)&userdata_; @@ -2454,7 +2454,7 @@ void mjCSite::Compile(void) { // initialize defaults mjCCamera::mjCCamera(mjCModel* _model, mjCDef* _def) { - mjm_defaultCamera(spec); + mjs_defaultCamera(spec); // clear private variables body = 0; @@ -2489,7 +2489,7 @@ mjCCamera& mjCCamera::operator=(const mjCCamera& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); } PointToLocal(); return *this; @@ -2509,7 +2509,7 @@ void mjCCamera::PointToLocal() { void mjCCamera::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; userdata_ = spec_userdata_; targetbody_ = spec_targetbody_; userdata = (mjDoubleVec)&userdata_; @@ -2608,7 +2608,7 @@ void mjCCamera::Compile(void) { // initialize defaults mjCLight::mjCLight(mjCModel* _model, mjCDef* _def) { - mjm_defaultLight(spec); + mjs_defaultLight(spec); // clear private variables body = 0; @@ -2640,7 +2640,7 @@ mjCLight& mjCLight::operator=(const mjCLight& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); } PointToLocal(); return *this; @@ -2659,7 +2659,7 @@ void mjCLight::PointToLocal() { void mjCLight::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; targetbody_ = spec_targetbody_; targetbody = (mjString)&targetbody_; } @@ -2704,7 +2704,7 @@ void mjCLight::Compile(void) { // constructor mjCHField::mjCHField(mjCModel* _model) { - mjm_defaultHField(spec); + mjs_defaultHField(spec); // set model pointer model = _model; @@ -2733,7 +2733,7 @@ mjCHField& mjCHField::operator=(const mjCHField& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); } PointToLocal(); return *this; @@ -2753,7 +2753,7 @@ void mjCHField::PointToLocal() { void mjCHField::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; file_ = spec_file_; content_type_ = spec_content_type_; userdata_ = spec_userdata_; @@ -2956,7 +2956,7 @@ void mjCHField::Compile(const mjVFS* vfs) { // initialize defaults mjCTexture::mjCTexture(mjCModel* _model) { - mjm_defaultTexture(spec); + mjs_defaultTexture(spec); // set model pointer model = _model; @@ -3010,7 +3010,7 @@ void mjCTexture::PointToLocal() { void mjCTexture::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; file_ = spec_file_; content_type_ = spec_content_type_; cubefiles_ = spec_cubefiles_; @@ -3698,7 +3698,7 @@ void mjCTexture::Compile(const mjVFS* vfs) { // initialize defaults mjCMaterial::mjCMaterial(mjCModel* _model, mjCDef* _def) { - mjm_defaultMaterial(spec); + mjs_defaultMaterial(spec); // clear internal spec_texture_.clear(); @@ -3732,7 +3732,7 @@ mjCMaterial& mjCMaterial::operator=(const mjCMaterial& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); } PointToLocal(); return *this; @@ -3751,7 +3751,7 @@ void mjCMaterial::PointToLocal() { void mjCMaterial::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; texture_ = spec_texture_; texture = (mjString)&texture_; } @@ -3769,7 +3769,7 @@ void mjCMaterial::Compile(void) { // constructor mjCPair::mjCPair(mjCModel* _model, mjCDef* _def) { - mjm_defaultPair(spec); + mjs_defaultPair(spec); // set defaults spec_geomname1_.clear(); @@ -3808,7 +3808,7 @@ mjCPair& mjCPair::operator=(const mjCPair& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); this->geom1 = nullptr; this->geom2 = nullptr; } @@ -3840,7 +3840,7 @@ void mjCPair::NameSpace(const mjCModel* m) { void mjCPair::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; geomname1_ = spec_geomname1_; geomname2_ = spec_geomname2_; geomname1 = (mjString)&geomname1_; @@ -4020,7 +4020,7 @@ mjCBodyPair& mjCBodyPair::operator=(const mjCBodyPair& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); } PointToLocal(); return *this; @@ -4049,7 +4049,7 @@ void mjCBodyPair::NameSpace(const mjCModel* m) { void mjCBodyPair::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; bodyname1_ = spec_bodyname1_; bodyname2_ = spec_bodyname2_; bodyname1 = (mjString)&bodyname1_; @@ -4104,7 +4104,7 @@ void mjCBodyPair::Compile(void) { // initialize default constraint mjCEquality::mjCEquality(mjCModel* _model, mjCDef* _def) { - mjm_defaultEquality(spec); + mjs_defaultEquality(spec); // clear internal variables spec_name1_.clear(); @@ -4139,7 +4139,7 @@ mjCEquality& mjCEquality::operator=(const mjCEquality& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); } PointToLocal(); return *this; @@ -4169,7 +4169,7 @@ void mjCEquality::NameSpace(const mjCModel* m) { void mjCEquality::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; name1_ = spec_name1_; name2_ = spec_name2_; name1 = (mjString)&name1_; @@ -4266,7 +4266,7 @@ void mjCEquality::Compile(void) { // constructor mjCTendon::mjCTendon(mjCModel* _model, mjCDef* _def) { - mjm_defaultTendon(spec); + mjs_defaultTendon(spec); // clear internal variables spec_material_.clear(); @@ -4302,7 +4302,7 @@ mjCTendon& mjCTendon::operator=(const mjCTendon& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); for (int i=0; itendon = this; @@ -4340,7 +4340,7 @@ void mjCTendon::NameSpace(const mjCModel* m) { void mjCTendon::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; material_ = spec_material_; userdata_ = spec_userdata_; material = (mjString)&material_; @@ -4622,7 +4622,7 @@ mjCWrap& mjCWrap::operator=(const mjCWrap& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); obj = nullptr; } PointToLocal(); @@ -4723,7 +4723,7 @@ void mjCWrap::ResolveReferences(const mjCModel* m) { // initialize defaults mjCActuator::mjCActuator(mjCModel* _model, mjCDef* _def) { - mjm_defaultActuator(spec); + mjs_defaultActuator(spec); // clear private variables ptarget = nullptr; @@ -4761,7 +4761,7 @@ mjCActuator& mjCActuator::operator=(const mjCActuator& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); ptarget = nullptr; } PointToLocal(); @@ -4803,7 +4803,7 @@ void mjCActuator::NameSpace(const mjCModel* m) { void mjCActuator::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; userdata_ = spec_userdata_; target_ = spec_target_; refsite_ = spec_refsite_; @@ -5066,7 +5066,7 @@ void mjCActuator::Compile(void) { // initialize defaults mjCSensor::mjCSensor(mjCModel* _model) { - mjm_defaultSensor(spec); + mjs_defaultSensor(spec); // set model model = _model; @@ -5098,7 +5098,7 @@ mjCSensor& mjCSensor::operator=(const mjCSensor& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); obj = nullptr; ref = nullptr; } @@ -5133,7 +5133,7 @@ void mjCSensor::NameSpace(const mjCModel* m) { void mjCSensor::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; userdata_ = spec_userdata_; objname_ = spec_objname_; refname_ = spec_refname_; @@ -5552,7 +5552,7 @@ void mjCSensor::Compile(void) { // constructor mjCNumeric::mjCNumeric(mjCModel* _model) { - mjm_defaultNumeric(spec); + mjs_defaultNumeric(spec); // set model pointer model = _model; @@ -5579,7 +5579,7 @@ mjCNumeric& mjCNumeric::operator=(const mjCNumeric& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); } PointToLocal(); return *this; @@ -5597,7 +5597,7 @@ void mjCNumeric::PointToLocal() { void mjCNumeric::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; data_ = spec_data_; data = (mjDoubleVec)&data_; } @@ -5640,7 +5640,7 @@ void mjCNumeric::Compile(void) { // constructor mjCText::mjCText(mjCModel* _model) { - mjm_defaultText(spec); + mjs_defaultText(spec); // set model pointer model = _model; @@ -5667,7 +5667,7 @@ mjCText& mjCText::operator=(const mjCText& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); } PointToLocal(); return *this; @@ -5685,7 +5685,7 @@ void mjCText::PointToLocal() { void mjCText::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; data_ = spec_data_; data = (mjString)&data_; } @@ -5716,7 +5716,7 @@ void mjCText::Compile(void) { // constructor mjCTuple::mjCTuple(mjCModel* _model) { - mjm_defaultTuple(spec); + mjs_defaultTuple(spec); // set model pointer model = _model; @@ -5746,7 +5746,7 @@ mjCTuple& mjCTuple::operator=(const mjCTuple& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); } PointToLocal(); return *this; @@ -5777,7 +5777,7 @@ void mjCTuple::NameSpace(const mjCModel* m) { void mjCTuple::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; objtype_ = spec_objtype_; objname_ = spec_objname_; objprm_ = spec_objprm_; @@ -5848,7 +5848,7 @@ void mjCTuple::Compile(void) { // constructor mjCKey::mjCKey(mjCModel* _model) { - mjm_defaultKey(spec); + mjs_defaultKey(spec); // set model pointer model = _model; @@ -5880,7 +5880,7 @@ mjCKey& mjCKey::operator=(const mjCKey& other) { if (this != &other) { this->spec = other.spec; *static_cast(this) = static_cast(other); - *static_cast(this) = static_cast(other); + *static_cast(this) = static_cast(other); } PointToLocal(); return *this; @@ -5903,7 +5903,7 @@ void mjCKey::PointToLocal() { void mjCKey::CopyFromSpec() { - *static_cast(this) = spec; + *static_cast(this) = spec; qpos_ = spec_qpos_; qvel_ = spec_qvel_; act_ = spec_act_; @@ -6031,7 +6031,7 @@ mjCPlugin::mjCPlugin(mjCModel* _model) { instance_name.clear(); // public interface - mjm_defaultPlugin(spec); + mjs_defaultPlugin(spec); spec.name = (mjString)&name; spec.instance_name = (mjString)&instance_name; spec.info = (mjString)&info; diff --git a/src/user/user_objects.h b/src/user/user_objects.h index 1a4cd0c6..0cf4fbde 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -82,7 +82,7 @@ class [[nodiscard]] mjCError { // alternative specifications of frame orientation -class mjCAlternative : public mjmOrientation { +class mjCAlternative : public mjsOrientation { public: mjCAlternative(); // constuctor const char* Set(double* quat, // set frame quat @@ -253,7 +253,7 @@ class mjCBody_ : public mjCBase { std::vector spec_userdata_; }; -class mjCBody : public mjCBody_, private mjmBody { +class mjCBody : public mjCBody_, private mjsBody { friend class mjCJoint; friend class mjCGeom; friend class mjCSite; @@ -300,7 +300,7 @@ class mjCBody : public mjCBody_, private mjmBody { const char* FullInertia(double quat[4], double inertia[3]); // variables set by user - mjmBody spec; + mjsBody spec; // inherited using mjCBase::name; @@ -343,7 +343,7 @@ class mjCFrame_ : public mjCBase { mjCAlternative alt_; }; -class mjCFrame : public mjCFrame_, private mjmFrame { +class mjCFrame : public mjCFrame_, private mjsFrame { friend class mjCBase; friend class mjCBody; friend class mjCGeom; @@ -354,7 +354,7 @@ class mjCFrame : public mjCFrame_, private mjmFrame { friend class mjCModel; public: - mjmFrame spec; + mjsFrame spec; using mjCBase::name; using mjCBase::classname; using mjCBase::info; @@ -389,7 +389,7 @@ class mjCJoint_ : public mjCBase { std::vector spec_userdata_; }; -class mjCJoint : public mjCJoint_, private mjmJoint { +class mjCJoint : public mjCJoint_, private mjsJoint { friend class mjCDef; friend class mjCEquality; friend class mjCBody; @@ -399,7 +399,7 @@ class mjCJoint : public mjCJoint_, private mjmJoint { friend class mjXURDF; public: - mjmJoint spec; + mjsJoint spec; using mjCBase::name; using mjCBase::classname; using mjCBase::info; @@ -457,7 +457,7 @@ class mjCGeom_ : public mjCBase { std::vector spec_userdata_; }; -class mjCGeom : public mjCGeom_, private mjmGeom { +class mjCGeom : public mjCGeom_, private mjsGeom { friend class mjCDef; friend class mjCMesh; friend class mjCPair; @@ -469,7 +469,7 @@ class mjCGeom : public mjCGeom_, private mjmGeom { public: using mjCBase::name; - mjmGeom spec; // variables set by user + mjsGeom spec; // variables set by user double GetVolume(void); // compute geom volume void SetInertia(void); // compute and set geom inertia bool IsVisual(void) const { return visual_; } @@ -526,7 +526,7 @@ class mjCSite_ : public mjCBase { int matid; // material id for rendering }; -class mjCSite : public mjCSite_, private mjmSite { +class mjCSite : public mjCSite_, private mjsSite { friend class mjCDef; friend class mjCBody; friend class mjCModel; @@ -534,9 +534,9 @@ class mjCSite : public mjCSite_, private mjmSite { friend class mjXURDF; public: - mjmSite spec; // variables set by user + mjsSite spec; // variables set by user - // use strings from mjCBase rather than mjStrings from mjmSite + // use strings from mjCBase rather than mjStrings from mjsSite using mjCBase::name; using mjCBase::classname; using mjCBase::info; @@ -572,7 +572,7 @@ class mjCCamera_ : public mjCBase { std::vector spec_userdata_; }; -class mjCCamera : public mjCCamera_, private mjmCamera { +class mjCCamera : public mjCCamera_, private mjsCamera { friend class mjCDef; friend class mjCBody; friend class mjCModel; @@ -580,7 +580,7 @@ class mjCCamera : public mjCCamera_, private mjmCamera { friend class mjXWriter; public: - mjmCamera spec; + mjsCamera spec; using mjCBase::name; using mjCBase::classname; using mjCBase::info; @@ -612,14 +612,14 @@ class mjCLight_ : public mjCBase { std::string spec_targetbody_; }; -class mjCLight : public mjCLight_, private mjmLight { +class mjCLight : public mjCLight_, private mjsLight { friend class mjCDef; friend class mjCBody; friend class mjCModel; friend class mjXWriter; public: - mjmLight spec; + mjsLight spec; using mjCBase::name; using mjCBase::classname; using mjCBase::info; @@ -673,7 +673,7 @@ class mjCFlex_ : public mjCBase { std::vector spec_texcoord_; }; -class mjCFlex: public mjCFlex_, private mjmFlex { +class mjCFlex: public mjCFlex_, private mjsFlex { friend class mjCDef; friend class mjCModel; friend class mjCFlexcomp; @@ -681,7 +681,7 @@ class mjCFlex: public mjCFlex_, private mjmFlex { friend class mjXWriter; public: - mjmFlex spec; + mjsFlex spec; using mjCBase::name; using mjCBase::classname; using mjCBase::info; @@ -777,7 +777,7 @@ class mjCMesh_ : public mjCBase { std::vector face_aabb_; // bounding boxes of all faces }; -class mjCMesh: public mjCMesh_, private mjmMesh { +class mjCMesh: public mjCMesh_, private mjsMesh { friend class mjCModel; friend class mjCFlexcomp; friend class mjXWriter; @@ -787,7 +787,7 @@ class mjCMesh: public mjCMesh_, private mjmMesh { mjCMesh& operator=(const mjCMesh& other); // copy assignment ~mjCMesh(); - mjmMesh spec; + mjsMesh spec; using mjCBase::name; using mjCBase::classname; using mjCBase::info; @@ -914,12 +914,12 @@ class mjCSkin_ : public mjCBase { std::vector bodyid; // body ids }; -class mjCSkin: public mjCSkin_, private mjmSkin { +class mjCSkin: public mjCSkin_, private mjsSkin { friend class mjCModel; friend class mjXWriter; public: - mjmSkin spec; + mjsSkin spec; using mjCBase::name; using mjCBase::classname; using mjCBase::info; @@ -968,13 +968,13 @@ class mjCHField_ : public mjCBase { std::vector spec_userdata_; }; -class mjCHField : public mjCHField_, private mjmHField { +class mjCHField : public mjCHField_, private mjsHField { friend class mjCGeom; friend class mjCModel; friend class mjXWriter; public: - mjmHField spec; + mjsHField spec; using mjCBase::name; using mjCBase::info; @@ -1015,7 +1015,7 @@ class mjCTexture_ : public mjCBase { std::vector spec_cubefiles_; }; -class mjCTexture : public mjCTexture_, private mjmTexture { +class mjCTexture : public mjCTexture_, private mjsTexture { friend class mjCModel; friend class mjXReader; friend class mjXWriter; @@ -1023,7 +1023,7 @@ class mjCTexture : public mjCTexture_, private mjmTexture { public: ~mjCTexture(); // destructor - mjmTexture spec; + mjsTexture spec; using mjCBase::name; using mjCBase::classname; using mjCBase::info; @@ -1072,13 +1072,13 @@ class mjCMaterial_ : public mjCBase { std::string spec_texture_; }; -class mjCMaterial : public mjCMaterial_, private mjmMaterial { +class mjCMaterial : public mjCMaterial_, private mjsMaterial { friend class mjCDef; friend class mjCModel; friend class mjXWriter; public: - mjmMaterial spec; + mjsMaterial spec; using mjCBase::name; using mjCBase::classname; using mjCBase::info; @@ -1111,14 +1111,14 @@ class mjCPair_ : public mjCBase { std::string spec_geomname2_; }; -class mjCPair : public mjCPair_, private mjmPair { +class mjCPair : public mjCPair_, private mjsPair { friend class mjCDef; friend class mjCBody; friend class mjCModel; friend class mjXWriter; public: - mjmPair spec; + mjsPair spec; using mjCBase::name; using mjCBase::classname; using mjCBase::info; @@ -1163,12 +1163,12 @@ class mjCBodyPair_ : public mjCBase { std::string spec_bodyname2_; }; -class mjCBodyPair : public mjCBodyPair_, private mjmExclude { +class mjCBodyPair : public mjCBodyPair_, private mjsExclude { friend class mjCBody; friend class mjCModel; public: - mjmExclude spec; + mjsExclude spec; using mjCBase::name; using mjCBase::info; @@ -1207,14 +1207,14 @@ class mjCEquality_ : public mjCBase { std::string spec_name2_; }; -class mjCEquality : public mjCEquality_, private mjmEquality { +class mjCEquality : public mjCEquality_, private mjsEquality { friend class mjCDef; friend class mjCBody; friend class mjCModel; friend class mjXWriter; public: - mjmEquality spec; + mjsEquality spec; using mjCBase::name; using mjCBase::classname; using mjCBase::info; @@ -1248,13 +1248,13 @@ class mjCTendon_ : public mjCBase { std::vector spec_userdata_; }; -class mjCTendon : public mjCTendon_, private mjmTendon { +class mjCTendon : public mjCTendon_, private mjsTendon { friend class mjCDef; friend class mjCModel; friend class mjXWriter; public: - mjmTendon spec; + mjsTendon spec; using mjCBase::name; using mjCBase::classname; using mjCBase::info; @@ -1308,12 +1308,12 @@ class mjCWrap_ : public mjCBase { std::string sidesite; // name of side site }; -class mjCWrap : public mjCWrap_, private mjmWrap { +class mjCWrap : public mjCWrap_, private mjsWrap { friend class mjCTendon; friend class mjCModel; public: - mjmWrap spec; + mjsWrap spec; using mjCBase::info; void PointToLocal(); @@ -1350,7 +1350,7 @@ class mjCPlugin : public mjCPlugin_ { friend class mjXWriter; public: - mjmPlugin spec; + mjsPlugin spec; mjCBase* parent; // parent object (only used when generating error message) mjCPlugin(const mjCPlugin& other); // copy constructor @@ -1383,13 +1383,13 @@ class mjCActuator_ : public mjCBase { std::vector spec_userdata_; }; -class mjCActuator : public mjCActuator_, private mjmActuator { +class mjCActuator : public mjCActuator_, private mjsActuator { friend class mjCDef; friend class mjCModel; friend class mjXWriter; public: - mjmActuator spec; + mjsActuator spec; using mjCBase::name; using mjCBase::classname; using mjCBase::info; @@ -1438,13 +1438,13 @@ class mjCSensor_ : public mjCBase { std::vector spec_userdata_; }; -class mjCSensor : public mjCSensor_, private mjmSensor { +class mjCSensor : public mjCSensor_, private mjsSensor { friend class mjCDef; friend class mjCModel; friend class mjXWriter; public: - mjmSensor spec; + mjsSensor spec; using mjCBase::name; using mjCBase::classname; using mjCBase::info; @@ -1480,12 +1480,12 @@ class mjCNumeric_ : public mjCBase { std::vector spec_data_; }; -class mjCNumeric : public mjCNumeric_, private mjmNumeric { +class mjCNumeric : public mjCNumeric_, private mjsNumeric { friend class mjCModel; friend class mjXWriter; public: - mjmNumeric spec; + mjsNumeric spec; using mjCBase::name; using mjCBase::info; @@ -1512,12 +1512,12 @@ class mjCText_ : public mjCBase { std::string spec_data_; }; -class mjCText : public mjCText_, private mjmText { +class mjCText : public mjCText_, private mjsText { friend class mjCModel; friend class mjXWriter; public: - mjmText spec; + mjsText spec; using mjCBase::name; using mjCBase::info; @@ -1549,12 +1549,12 @@ class mjCTuple_ : public mjCBase { std::vector spec_objprm_; }; -class mjCTuple : public mjCTuple_, private mjmTuple { +class mjCTuple : public mjCTuple_, private mjsTuple { friend class mjCModel; friend class mjXWriter; public: - mjmTuple spec; + mjsTuple spec; using mjCBase::name; using mjCBase::info; @@ -1593,12 +1593,12 @@ class mjCKey_ : public mjCBase { std::vector spec_ctrl_; }; -class mjCKey : public mjCKey_, private mjmKey { +class mjCKey : public mjCKey_, private mjsKey { friend class mjCModel; friend class mjXWriter; public: - mjmKey spec; + mjsKey spec; using mjCBase::name; using mjCBase::info; diff --git a/src/xml/xml.cc b/src/xml/xml.cc index e6919948..064d52f3 100644 --- a/src/xml/xml.cc +++ b/src/xml/xml.cc @@ -345,14 +345,14 @@ mjSpec* mjParseXML(const char* filename, const mjVFS* vfs, } // create model, set filedir - model = mjm_createSpec(); + model = mjs_createSpec(); const char* dir; int ndir = 0; mju_getResourceDir(resource, &dir, &ndir); if (dir != nullptr) { - mjm_setString(model->modelfiledir, std::string(dir, ndir).c_str()); + mjs_setString(model->modelfiledir, std::string(dir, ndir).c_str()); } else { - mjm_setString(model->modelfiledir, ""); + mjs_setString(model->modelfiledir, ""); } // close resource @@ -364,8 +364,8 @@ mjSpec* mjParseXML(const char* filename, const mjVFS* vfs, // find include elements, replace them with subtree from xml file std::unordered_set included = {filename}; mjXReader parser; - parser.SetModelFileDir(mjm_getString(model->modelfiledir)); - mjIncludeXML(parser, root, mjm_getString(model->modelfiledir), vfs, included); + parser.SetModelFileDir(mjs_getString(model->modelfiledir)); + mjIncludeXML(parser, root, mjs_getString(model->modelfiledir), vfs, included); // parse MuJoCo model parser.SetModel(model); @@ -394,7 +394,7 @@ mjSpec* mjParseXML(const char* filename, const mjVFS* vfs, // catch known errors catch (mjXError err) { mjCopyError(error, err.message, error_sz); - mjm_deleteSpec(model); + mjs_deleteSpec(model); return nullptr; } diff --git a/src/xml/xml_api.cc b/src/xml/xml_api.cc index 9b8a96e8..a827ddef 100644 --- a/src/xml/xml_api.cc +++ b/src/xml/xml_api.cc @@ -56,7 +56,7 @@ std::optional GlobalModel::ToXML(const mjModel* m, char* error, mjCopyError(error, "No XML model loaded", error_sz); return std::nullopt; } - mjm_copyBack(model_, m); + mjs_copyBack(model_, m); std::string result = mjWriteXML(model_, error, error_sz); if (result.empty()) { return std::nullopt; @@ -67,7 +67,7 @@ std::optional GlobalModel::ToXML(const mjModel* m, char* error, void GlobalModel::Set(mjSpec* model) { std::lock_guard lock(*mutex_); if (model_ != nullptr) { - mjm_deleteSpec(model_); + mjs_deleteSpec(model_); } model_ = model; } @@ -93,21 +93,21 @@ mjModel* mj_loadXML(const char* filename, const mjVFS* vfs, // parse new model std::unique_ptr> model( mjParseXML(filename, vfs, error, error_sz), - [](mjSpec* m) { mjm_deleteSpec(m); }); + [](mjSpec* m) { mjs_deleteSpec(m); }); if (!model) { return nullptr; } // compile new model - mjModel* m = mjm_compile(model.get(), vfs); + mjModel* m = mjs_compile(model.get(), vfs); if (!m) { - mjCopyError(error, mjm_getError(model.get()), error_sz); + mjCopyError(error, mjs_getError(model.get()), error_sz); return nullptr; } // handle compile warning - if (mjm_isWarning(model.get())) { - mjCopyError(error, mjm_getError(model.get()), error_sz); + if (mjs_isWarning(model.get())) { + mjCopyError(error, mjs_getError(model.get()), error_sz); } else if (error) { error[0] = '\0'; } diff --git a/src/xml/xml_base.cc b/src/xml/xml_base.cc index 60a854b5..d440dd2b 100644 --- a/src/xml/xml_base.cc +++ b/src/xml/xml_base.cc @@ -24,6 +24,7 @@ #include "user/user_api.h" #include "user/user_model.h" #include "user/user_objects.h" +#include "xml/xml_util.h" #include "tinyxml2.h" namespace { @@ -51,7 +52,7 @@ void mjXBase::SetModel(mjSpec* _model) { // read alternative orientation specification -int mjXBase::ReadAlternative(XMLElement* elem, mjmOrientation& alt) { +int mjXBase::ReadAlternative(XMLElement* elem, mjsOrientation& alt) { string text; int read = (int)(elem->Attribute("quat") != 0) + (ReadAttr(elem, "axisangle", 4, alt.axisangle, text) ? 1 : 0) + diff --git a/src/xml/xml_base.h b/src/xml/xml_base.h index 662d9e7e..26d95fcb 100644 --- a/src/xml/xml_base.h +++ b/src/xml/xml_base.h @@ -90,7 +90,7 @@ class mjXBase : public mjXUtil { virtual void SetModel(mjSpec*); // read alternative orientation specification - static int ReadAlternative(tinyxml2::XMLElement* elem, mjmOrientation& alt); + static int ReadAlternative(tinyxml2::XMLElement* elem, mjsOrientation& alt); protected: mjSpec* model; // internally-allocated model diff --git a/src/xml/xml_native_reader.cc b/src/xml/xml_native_reader.cc index 4d72f0b0..667364d3 100644 --- a/src/xml/xml_native_reader.cc +++ b/src/xml/xml_native_reader.cc @@ -48,7 +48,7 @@ using std::string; using std::vector; using tinyxml2::XMLElement; -void ReadPluginConfigs(tinyxml2::XMLElement* elem, mjmPlugin* p) { +void ReadPluginConfigs(tinyxml2::XMLElement* elem, mjsPlugin* p) { std::map> config_attribs; XMLElement* child = FirstChildElement(elem); while (child) { @@ -71,7 +71,7 @@ void ReadPluginConfigs(tinyxml2::XMLElement* elem, mjmPlugin* p) { "plugin configuration attributes cannot be used in an " "element that references a predefined plugin instance"); } else if (p) { - mjm_setPluginAttributes(p, &config_attribs); + mjs_setPluginAttributes(p, &config_attribs); } } } // namespace @@ -808,14 +808,14 @@ void mjXReader::Parse(XMLElement* root) { // get model name string modelname; if (ReadAttrTxt(root, "model", modelname)) { - mjm_setString(model->modelname, modelname.c_str()); + mjs_setString(model->modelname, modelname.c_str()); } // get comment if (root->FirstChild() && root->FirstChild()->ToComment()) { - mjm_setString(model->comment, root->FirstChild()->Value()); + mjs_setString(model->comment, root->FirstChild()->Value()); } else { - mjm_setString(model->comment, ""); + mjs_setString(model->comment, ""); } //------------------- parse MuJoCo sections embedded in all XML formats @@ -871,7 +871,7 @@ void mjXReader::Parse(XMLElement* root) { for (XMLElement* section = FirstChildElement(root, "worldbody"); section; section = NextSiblingElement(section, "worldbody")) { - Body(section, mjm_findBody(model, "world"), nullptr); + Body(section, mjs_findBody(model, "world"), nullptr); } for (XMLElement* section = FirstChildElement(root, "contact"); section; @@ -949,16 +949,16 @@ void mjXReader::Compiler(XMLElement* section, mjSpec* mod) { memcpy(mod->euler, text.c_str(), 3); } if (ReadAttrTxt(section, "assetdir", text)) { - mjm_setString(mod->meshdir, text.c_str()); - mjm_setString(mod->texturedir, text.c_str()); + mjs_setString(mod->meshdir, text.c_str()); + mjs_setString(mod->texturedir, text.c_str()); } // meshdir and texturedir take precedence over assetdir std::string meshdir, texturedir; if (ReadAttrTxt(section, "meshdir", meshdir)) { - mjm_setString(mod->meshdir, meshdir.c_str()); + mjs_setString(mod->meshdir, meshdir.c_str()); }; if (ReadAttrTxt(section, "texturedir", texturedir)) { - mjm_setString(mod->texturedir, texturedir.c_str()); + mjs_setString(mod->texturedir, texturedir.c_str()); } if (MapValue(section, "discardvisual", &n, bool_map, 2)) { mod->discardvisual = (n==1); @@ -1276,19 +1276,19 @@ void mjXReader::Statistic(XMLElement* section) { //---------------------------------- one-element parsers ------------------------------------------- // flex element parser -void mjXReader::OneFlex(XMLElement* elem, mjmFlex* pflex) { +void mjXReader::OneFlex(XMLElement* elem, mjsFlex* pflex) { string text, name, classname, material; int n; // read attributes if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(pflex->name, name.c_str()); + mjs_setString(pflex->name, name.c_str()); } if (ReadAttrTxt(elem, "classname", classname)) { - mjm_setString(pflex->classname, classname.c_str()); + mjs_setString(pflex->classname, classname.c_str()); } if (ReadAttrTxt(elem, "material", material)) { - mjm_setString(pflex->material, material.c_str()); + mjs_setString(pflex->material, material.c_str()); } ReadAttr(elem, "radius", 1, &pflex->radius, text); @@ -1301,19 +1301,19 @@ void mjXReader::OneFlex(XMLElement* elem, mjmFlex* pflex) { // read data vectors if (ReadAttrTxt(elem, "body", text, true)) { - mjm_setStringVec(pflex->vertbody, text.c_str()); + mjs_setStringVec(pflex->vertbody, text.c_str()); } if (ReadAttrTxt(elem, "vertex", text)) { std::vector vert = String2Vector(text); - mjm_setDouble(pflex->vert, vert.data(), vert.size()); + mjs_setDouble(pflex->vert, vert.data(), vert.size()); } if (ReadAttrTxt(elem, "element", text, true)) { std::vector elem = String2Vector(text); - mjm_setInt(pflex->elem, elem.data(), elem.size()); + mjs_setInt(pflex->elem, elem.data(), elem.size()); } if (ReadAttrTxt(elem, "texcoord", text)) { std::vector texcoord = String2Vector(text); - mjm_setFloat(pflex->texcoord, texcoord.data(), texcoord.size()); + mjs_setFloat(pflex->texcoord, texcoord.data(), texcoord.size()); } // contact subelement @@ -1344,29 +1344,29 @@ void mjXReader::OneFlex(XMLElement* elem, mjmFlex* pflex) { } // write error info - mjm_setString(pflex->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(pflex->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); } // mesh element parser -void mjXReader::OneMesh(XMLElement* elem, mjmMesh* pmesh) { +void mjXReader::OneMesh(XMLElement* elem, mjsMesh* pmesh) { int n; string text, name, classname, content_type; // read attributes if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(pmesh->name, name.c_str()); + mjs_setString(pmesh->name, name.c_str()); } if (ReadAttrTxt(elem, "class", classname)) { - mjm_setString(pmesh->classname, classname.c_str()); + mjs_setString(pmesh->classname, classname.c_str()); } if (ReadAttrTxt(elem, "content_type", content_type)) { - mjm_setString(pmesh->content_type, content_type.c_str()); + mjs_setString(pmesh->content_type, content_type.c_str()); } auto file = ReadAttrFile(elem, "file", MeshDir()); if (file) { - mjm_setString(pmesh->file, file->c_str()); + mjs_setString(pmesh->file, file->c_str()); } ReadAttr(elem, "refpos", 3, pmesh->refpos, text); ReadAttr(elem, "refquat", 4, pmesh->refquat, text); @@ -1385,7 +1385,7 @@ void mjXReader::OneMesh(XMLElement* elem, mjmMesh* pmesh) { if (ReadAttrTxt(elem, "vertex", text)) { auto uservert = ReadAttrVec(elem, "vertex"); if (uservert.has_value()) { - mjm_setFloat(pmesh->uservert, uservert->data(), uservert->size()); + mjs_setFloat(pmesh->uservert, uservert->data(), uservert->size()); } } @@ -1393,7 +1393,7 @@ void mjXReader::OneMesh(XMLElement* elem, mjmMesh* pmesh) { if (ReadAttrTxt(elem, "normal", text)) { auto usernormal = ReadAttrVec(elem, "normal"); if (usernormal.has_value()) { - mjm_setFloat(pmesh->usernormal, usernormal->data(), usernormal->size()); + mjs_setFloat(pmesh->usernormal, usernormal->data(), usernormal->size()); } } @@ -1401,7 +1401,7 @@ void mjXReader::OneMesh(XMLElement* elem, mjmMesh* pmesh) { if (ReadAttrTxt(elem, "texcoord", text)) { auto usertexcoord = ReadAttrVec(elem, "texcoord"); if (usertexcoord.has_value()) { - mjm_setFloat(pmesh->usertexcoord, usertexcoord->data(), usertexcoord->size()); + mjs_setFloat(pmesh->usertexcoord, usertexcoord->data(), usertexcoord->size()); } } @@ -1409,31 +1409,31 @@ void mjXReader::OneMesh(XMLElement* elem, mjmMesh* pmesh) { if (ReadAttrTxt(elem, "face", text)) { auto userface = ReadAttrVec(elem, "face"); if (userface.has_value()) { - mjm_setInt(pmesh->userface, userface->data(), userface->size()); + mjs_setInt(pmesh->userface, userface->data(), userface->size()); } } // write error info - mjm_setString(pmesh->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(pmesh->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); } // skin element parser -void mjXReader::OneSkin(XMLElement* elem, mjmSkin* pskin) { +void mjXReader::OneSkin(XMLElement* elem, mjsSkin* pskin) { string text, name, material; float data[4]; // read attributes if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(pskin->name, name.c_str()); + mjs_setString(pskin->name, name.c_str()); } auto file = ReadAttrFile(elem, "file", AssetDir()); if (file.has_value()) { - mjm_setString(pskin->file, file->c_str()); + mjs_setString(pskin->file, file->c_str()); } if (ReadAttrTxt(elem, "material", material)) { - mjm_setString(pskin->material, material.c_str()); + mjs_setString(pskin->material, material.c_str()); } ReadAttrInt(elem, "group", &pskin->group); if (pskin->group<0 || pskin->group>=mjNGROUP) { @@ -1445,19 +1445,19 @@ void mjXReader::OneSkin(XMLElement* elem, mjmSkin* pskin) { // read vertex data if (ReadAttrTxt(elem, "vertex", text)) { std::vector vert = String2Vector(text); - mjm_setFloat(pskin->vert, vert.data(), vert.size()); + mjs_setFloat(pskin->vert, vert.data(), vert.size()); } // read texcoord data if (ReadAttrTxt(elem, "texcoord", text)) { std::vector texcoord = String2Vector(text); - mjm_setFloat(pskin->texcoord, texcoord.data(), texcoord.size()); + mjs_setFloat(pskin->texcoord, texcoord.data(), texcoord.size()); } // read user face data if (ReadAttrTxt(elem, "face", text)) { std::vector face = String2Vector(text); - mjm_setInt(pskin->face, face.data(), face.size()); + mjs_setInt(pskin->face, face.data(), face.size()); } // read bones @@ -1468,7 +1468,7 @@ void mjXReader::OneSkin(XMLElement* elem, mjmSkin* pskin) { while (bone) { // read body ReadAttrTxt(bone, "body", text, true); - mjm_appendString(pskin->bodyname, text.c_str()); + mjs_appendString(pskin->bodyname, text.c_str()); // read bindpos ReadAttr(bone, "bindpos", 3, data, text, true); @@ -1486,41 +1486,41 @@ void mjXReader::OneSkin(XMLElement* elem, mjmSkin* pskin) { // read vertid ReadAttrTxt(bone, "vertid", text, true); vector tempid = String2Vector(text); - mjm_appendIntVec(pskin->vertid, tempid.data(), tempid.size()); + mjs_appendIntVec(pskin->vertid, tempid.data(), tempid.size()); // read vertweight ReadAttrTxt(bone, "vertweight", text, true); vector tempweight = String2Vector(text); - mjm_appendFloatVec(pskin->vertweight, tempweight.data(), tempweight.size()); + mjs_appendFloatVec(pskin->vertweight, tempweight.data(), tempweight.size()); // advance to next bone bone = NextSiblingElement(bone, "bone"); } // set bind vectors - mjm_setFloat(pskin->bindpos, bindpos.data(), bindpos.size()); - mjm_setFloat(pskin->bindquat, bindquat.data(), bindquat.size()); + mjs_setFloat(pskin->bindpos, bindpos.data(), bindpos.size()); + mjs_setFloat(pskin->bindquat, bindquat.data(), bindquat.size()); // write error info - mjm_setString(pskin->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(pskin->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); } // material element parser -void mjXReader::OneMaterial(XMLElement* elem, mjmMaterial* pmat) { +void mjXReader::OneMaterial(XMLElement* elem, mjsMaterial* pmat) { string text, name, classname, texture; int n; // read attributes if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(pmat->name, name.c_str()); + mjs_setString(pmat->name, name.c_str()); } if (ReadAttrTxt(elem, "class", classname)) { - mjm_setString(pmat->classname, classname.c_str()); + mjs_setString(pmat->classname, classname.c_str()); } if (ReadAttrTxt(elem, "texture", texture)) { - mjm_setString(pmat->texture, texture.c_str()); + mjs_setString(pmat->texture, texture.c_str()); } if (MapValue(elem, "texuniform", &n, bool_map, 2)) { pmat->texuniform = (n==1); @@ -1533,23 +1533,23 @@ void mjXReader::OneMaterial(XMLElement* elem, mjmMaterial* pmat) { ReadAttr(elem, "rgba", 4, pmat->rgba, text); // write error info - mjm_setString(pmat->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(pmat->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); } // joint element parser -void mjXReader::OneJoint(XMLElement* elem, mjmJoint* pjoint) { +void mjXReader::OneJoint(XMLElement* elem, mjsJoint* pjoint) { string text, name, classname; std::vector userdata; int n; // read attributes if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(pjoint->name, name.c_str()); + mjs_setString(pjoint->name, name.c_str()); } if (ReadAttrTxt(elem, "class", classname)) { - mjm_setString(pjoint->classname, classname.c_str()); + mjs_setString(pjoint->classname, classname.c_str()); } if (MapValue(elem, "type", &n, joint_map, joint_sz)) { pjoint->type = (mjtJoint)n; @@ -1576,17 +1576,17 @@ void mjXReader::OneJoint(XMLElement* elem, mjmJoint* pjoint) { // read userdata if (ReadVector(elem, "user", userdata, text)) { - mjm_setDouble(pjoint->userdata, userdata.data(), userdata.size()); + mjs_setDouble(pjoint->userdata, userdata.data(), userdata.size()); } // write error info - mjm_setString(pjoint->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(pjoint->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); } // geom element parser -void mjXReader::OneGeom(XMLElement* elem, mjmGeom* pgeom) { +void mjXReader::OneGeom(XMLElement* elem, mjsGeom* pgeom) { string text, name, classname; std::vector userdata; std::string hfieldname, meshname, material; @@ -1594,10 +1594,10 @@ void mjXReader::OneGeom(XMLElement* elem, mjmGeom* pgeom) { // read attributes if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(pgeom->name, name.c_str()); + mjs_setString(pgeom->name, name.c_str()); } if (ReadAttrTxt(elem, "class", classname)) { - mjm_setString(pgeom->classname, classname.c_str()); + mjs_setString(pgeom->classname, classname.c_str()); } if (MapValue(elem, "type", &n, geom_map, mjNGEOMTYPES)) { pgeom->type = (mjtGeom)n; @@ -1615,14 +1615,14 @@ void mjXReader::OneGeom(XMLElement* elem, mjmGeom* pgeom) { ReadAttr(elem, "margin", 1, &pgeom->margin, text); ReadAttr(elem, "gap", 1, &pgeom->gap, text); if (ReadAttrTxt(elem, "hfield", hfieldname)) { - mjm_setString(pgeom->hfieldname, hfieldname.c_str()); + mjs_setString(pgeom->hfieldname, hfieldname.c_str()); } if (ReadAttrTxt(elem, "mesh", meshname)) { - mjm_setString(pgeom->meshname, meshname.c_str()); + mjs_setString(pgeom->meshname, meshname.c_str()); } ReadAttr(elem, "fitscale", 1, &pgeom->fitscale, text); if (ReadAttrTxt(elem, "material", material)) { - mjm_setString(pgeom->material, material.c_str()); + mjs_setString(pgeom->material, material.c_str()); } ReadAttr(elem, "rgba", 4, pgeom->rgba, text); if (MapValue(elem, "fluidshape", &n, fluid_map, 2)) { @@ -1632,7 +1632,7 @@ void mjXReader::OneGeom(XMLElement* elem, mjmGeom* pgeom) { // read userdata if (ReadVector(elem, "user", userdata, text)) { - mjm_setDouble(pgeom->userdata, userdata.data(), userdata.size()); + mjs_setDouble(pgeom->userdata, userdata.data(), userdata.size()); } // plugin sub-element @@ -1655,13 +1655,13 @@ void mjXReader::OneGeom(XMLElement* elem, mjmGeom* pgeom) { } // write error info - mjm_setString(pgeom->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(pgeom->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); } // site element parser -void mjXReader::OneSite(XMLElement* elem, mjmSite* site) { +void mjXReader::OneSite(XMLElement* elem, mjsSite* site) { int n; string text, name, classname; std::vector userdata; @@ -1669,10 +1669,10 @@ void mjXReader::OneSite(XMLElement* elem, mjmSite* site) { // read attributes if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(site->name, name.c_str()); + mjs_setString(site->name, name.c_str()); } if (ReadAttrTxt(elem, "class", classname)) { - mjm_setString(site->classname, classname.c_str()); + mjs_setString(site->classname, classname.c_str()); } if (MapValue(elem, "type", &n, geom_map, mjNGEOMTYPES)) { site->type = (mjtGeom)n; @@ -1682,36 +1682,36 @@ void mjXReader::OneSite(XMLElement* elem, mjmSite* site) { ReadAttr(elem, "pos", 3, site->pos, text); ReadQuat(elem, "quat", site->quat, text); if (ReadAttrTxt(elem, "material", material)) { - mjm_setString(site->material, material.c_str()); + mjs_setString(site->material, material.c_str()); } ReadAttr(elem, "rgba", 4, site->rgba, text); ReadAttr(elem, "fromto", 6, site->fromto, text); ReadAlternative(elem, site->alt); if (ReadVector(elem, "user", userdata, text)) { - mjm_setDouble(site->userdata, userdata.data(), userdata.size()); + mjs_setDouble(site->userdata, userdata.data(), userdata.size()); } // write error info - mjm_setString(site->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(site->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); } // camera element parser -void mjXReader::OneCamera(XMLElement* elem, mjmCamera* pcam) { +void mjXReader::OneCamera(XMLElement* elem, mjsCamera* pcam) { int n; string text, name, classname, targetbody; std::vector userdata; // read attributes if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(pcam->name, name.c_str()); + mjs_setString(pcam->name, name.c_str()); } if (ReadAttrTxt(elem, "class", classname)) { - mjm_setString(pcam->classname, classname.c_str()); + mjs_setString(pcam->classname, classname.c_str()); } if (ReadAttrTxt(elem, "target", targetbody)) { - mjm_setString(pcam->targetbody, targetbody.c_str()); + mjs_setString(pcam->targetbody, targetbody.c_str()); } if (MapValue(elem, "mode", &n, camlight_map, camlight_sz)) { pcam->mode = (mjtCamLight)n; @@ -1743,28 +1743,28 @@ void mjXReader::OneCamera(XMLElement* elem, mjmCamera* pcam) { // read userdata ReadVector(elem, "user", userdata, text); - mjm_setDouble(pcam->userdata, userdata.data(), userdata.size()); + mjs_setDouble(pcam->userdata, userdata.data(), userdata.size()); // write error info - mjm_setString(pcam->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(pcam->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); } // light element parser -void mjXReader::OneLight(XMLElement* elem, mjmLight* plight) { +void mjXReader::OneLight(XMLElement* elem, mjsLight* plight) { int n; string text, name, classname, targetbody; // read attributes if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(plight->name, name.c_str()); + mjs_setString(plight->name, name.c_str()); } if (ReadAttrTxt(elem, "class", classname)) { - mjm_setString(plight->classname, classname.c_str()); + mjs_setString(plight->classname, classname.c_str()); } if (ReadAttrTxt(elem, "target", targetbody)) { - mjm_setString(plight->targetbody, targetbody.c_str()); + mjs_setString(plight->targetbody, targetbody.c_str()); } if (MapValue(elem, "mode", &n, camlight_map, camlight_sz)) { plight->mode = (mjtCamLight)n; @@ -1788,31 +1788,31 @@ void mjXReader::OneLight(XMLElement* elem, mjmLight* plight) { ReadAttr(elem, "specular", 3, plight->specular, text); // write error info - mjm_setString(plight->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(plight->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); } // pair element parser -void mjXReader::OnePair(XMLElement* elem, mjmPair* ppair) { +void mjXReader::OnePair(XMLElement* elem, mjsPair* ppair) { string text, name, classname, geomname1, geomname2; // regular only if (!readingdefaults) { if (ReadAttrTxt(elem, "class", classname)) { - mjm_setString(ppair->classname, classname.c_str()); + mjs_setString(ppair->classname, classname.c_str()); } if (ReadAttrTxt(elem, "geom1", geomname1)) { - mjm_setString(ppair->geomname1, geomname1.c_str()); + mjs_setString(ppair->geomname1, geomname1.c_str()); } if (ReadAttrTxt(elem, "geom2", geomname2)) { - mjm_setString(ppair->geomname2, geomname2.c_str()); + mjs_setString(ppair->geomname2, geomname2.c_str()); } } // read other parameters if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(ppair->name, name.c_str()); + mjs_setString(ppair->name, name.c_str()); } ReadAttrInt(elem, "condim", &ppair->condim); ReadAttr(elem, "solref", mjNREF, ppair->solref, text, false, false); @@ -1823,13 +1823,13 @@ void mjXReader::OnePair(XMLElement* elem, mjmPair* ppair) { ReadAttr(elem, "friction", 5, ppair->friction, text, false, false); // write error info - mjm_setString(ppair->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(ppair->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); } // equality element parser -void mjXReader::OneEquality(XMLElement* elem, mjmEquality* pequality) { +void mjXReader::OneEquality(XMLElement* elem, mjsEquality* pequality) { int n; string text, name1, name2, name, classname; @@ -1840,10 +1840,10 @@ void mjXReader::OneEquality(XMLElement* elem, mjmEquality* pequality) { // regular only if (!readingdefaults) { if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(pequality->name, name.c_str()); + mjs_setString(pequality->name, name.c_str()); } if (ReadAttrTxt(elem, "class", classname)) { - mjm_setString(pequality->classname, classname.c_str()); + mjs_setString(pequality->classname, classname.c_str()); }; switch (pequality->type) { @@ -1887,9 +1887,9 @@ void mjXReader::OneEquality(XMLElement* elem, mjmEquality* pequality) { throw mjXError(elem, "unrecognized equality constraint type"); } - mjm_setString(pequality->name1, name1.c_str()); + mjs_setString(pequality->name1, name1.c_str()); if (!name2.empty()) { - mjm_setString(pequality->name2, name2.c_str()); + mjs_setString(pequality->name2, name2.c_str()); } } @@ -1901,26 +1901,26 @@ void mjXReader::OneEquality(XMLElement* elem, mjmEquality* pequality) { ReadAttr(elem, "solimp", mjNIMP, pequality->solimp, text, false, false); // write error info - mjm_setString(pequality->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(pequality->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); } // tendon element parser -void mjXReader::OneTendon(XMLElement* elem, mjmTendon* pten) { +void mjXReader::OneTendon(XMLElement* elem, mjsTendon* pten) { string text, name, classname, material; std::vector userdata; // read attributes if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(pten->name, name.c_str()); + mjs_setString(pten->name, name.c_str()); } if (ReadAttrTxt(elem, "class", classname)) { - mjm_setString(pten->classname, classname.c_str()); + mjs_setString(pten->classname, classname.c_str()); } ReadAttrInt(elem, "group", &pten->group); if (ReadAttrTxt(elem, "material", material)) { - mjm_setString(pten->material, material.c_str()); + mjs_setString(pten->material, material.c_str()); } MapValue(elem, "limited", &pten->limited, TFAuto_map, 3); ReadAttr(elem, "width", 1, &pten->width, text); @@ -1941,25 +1941,25 @@ void mjXReader::OneTendon(XMLElement* elem, mjmTendon* pten) { // read userdata if (ReadVector(elem, "user", userdata, text)) { - mjm_setDouble(pten->userdata, userdata.data(), userdata.size()); + mjs_setDouble(pten->userdata, userdata.data(), userdata.size()); } // write error info - mjm_setString(pten->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(pten->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); } // actuator element parser -void mjXReader::OneActuator(XMLElement* elem, mjmActuator* pact) { +void mjXReader::OneActuator(XMLElement* elem, mjsActuator* pact) { string text, type, name, classname, target, slidersite, refsite; // common attributes if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(pact->name, name.c_str()); + mjs_setString(pact->name, name.c_str()); } if (ReadAttrTxt(elem, "class", classname)) { - mjm_setString(pact->classname, classname.c_str()); + mjs_setString(pact->classname, classname.c_str()); } ReadAttrInt(elem, "group", &pact->group); MapValue(elem, "ctrllimited", &pact->ctrllimited, TFAuto_map, 3); @@ -1974,32 +1974,32 @@ void mjXReader::OneActuator(XMLElement* elem, mjmActuator* pact) { // transmission target and type int cnt = 0; if (ReadAttrTxt(elem, "joint", target)) { - mjm_setString(pact->target, target.c_str()); + mjs_setString(pact->target, target.c_str()); pact->trntype = mjTRN_JOINT; cnt++; } if (ReadAttrTxt(elem, "jointinparent", target)) { - mjm_setString(pact->target, target.c_str()); + mjs_setString(pact->target, target.c_str()); pact->trntype = mjTRN_JOINTINPARENT; cnt++; } if (ReadAttrTxt(elem, "tendon", target)) { - mjm_setString(pact->target, target.c_str()); + mjs_setString(pact->target, target.c_str()); pact->trntype = mjTRN_TENDON; cnt++; } if (ReadAttrTxt(elem, "cranksite", target)) { - mjm_setString(pact->target, target.c_str()); + mjs_setString(pact->target, target.c_str()); pact->trntype = mjTRN_SLIDERCRANK; cnt++; } if (ReadAttrTxt(elem, "site", target)) { - mjm_setString(pact->target, target.c_str()); + mjs_setString(pact->target, target.c_str()); pact->trntype = mjTRN_SITE; cnt++; } if (ReadAttrTxt(elem, "body", target)) { - mjm_setString(pact->target, target.c_str()); + mjs_setString(pact->target, target.c_str()); pact->trntype = mjTRN_BODY; cnt++; } @@ -2012,7 +2012,7 @@ void mjXReader::OneActuator(XMLElement* elem, mjmActuator* pact) { int r1 = ReadAttr(elem, "cranklength", 1, &pact->cranklength, text); int r2 = ReadAttrTxt(elem, "slidersite", slidersite); if (r2) { - mjm_setString(pact->slidersite, slidersite.c_str()); + mjs_setString(pact->slidersite, slidersite.c_str()); } if ((r1 || r2) && pact->trntype!=mjTRN_SLIDERCRANK && pact->trntype!=mjTRN_UNDEFINED) { throw mjXError(elem, "cranklength and slidersite can only be used in slidercrank transmission"); @@ -2021,7 +2021,7 @@ void mjXReader::OneActuator(XMLElement* elem, mjmActuator* pact) { // site-specific parameters (refsite) int r3 = ReadAttrTxt(elem, "refsite", refsite); if (r3) { - mjm_setString(pact->refsite, refsite.c_str()); + mjs_setString(pact->refsite, refsite.c_str()); } if (r3 && pact->trntype!=mjTRN_SITE && pact->trntype!=mjTRN_UNDEFINED) { throw mjXError(elem, "refsite can only be used with site transmission"); @@ -2231,17 +2231,17 @@ void mjXReader::OneActuator(XMLElement* elem, mjmActuator* pact) { // read userdata std::vector userdata; if (ReadVector(elem, "user", userdata, text)) { - mjm_setDouble(pact->userdata, userdata.data(), userdata.size()); + mjs_setDouble(pact->userdata, userdata.data(), userdata.size()); } // write info - mjm_setString(pact->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(pact->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); } // make composite -void mjXReader::OneComposite(XMLElement* elem, mjmBody* pbody, mjmDefault* def) { +void mjXReader::OneComposite(XMLElement* elem, mjsBody* pbody, mjmDefault* def) { string text; int n; @@ -2318,7 +2318,7 @@ void mjXReader::OneComposite(XMLElement* elem, mjmBody* pbody, mjmDefault* def) XMLElement* egeom = FirstChildElement(elem, "geom"); if (egeom) { std::string material; - mjmGeom& dgeom = *comp.def[0].spec.geom; + mjsGeom& dgeom = *comp.def[0].spec.geom; if (MapValue(egeom, "type", &n, geom_map, mjNGEOMTYPES)) { dgeom.type = (mjtGeom)n; } @@ -2335,7 +2335,7 @@ void mjXReader::OneComposite(XMLElement* elem, mjmBody* pbody, mjmDefault* def) ReadAttr(egeom, "margin", 1, &dgeom.margin, text); ReadAttr(egeom, "gap", 1, &dgeom.gap, text); if (ReadAttrTxt(egeom, "material", material)) { - mjm_setString(dgeom.material, material.c_str()); + mjs_setString(dgeom.material, material.c_str()); } ReadAttr(egeom, "rgba", 4, dgeom.rgba, text); ReadAttr(egeom, "mass", 1, &dgeom.mass, text); @@ -2346,12 +2346,12 @@ void mjXReader::OneComposite(XMLElement* elem, mjmBody* pbody, mjmDefault* def) XMLElement* esite = FirstChildElement(elem, "site"); if (esite) { std::string material; - mjmSite& dsite = *comp.def[0].spec.site; + mjsSite& dsite = *comp.def[0].spec.site; ReadAttr(esite, "size", 3, dsite.size, text, false, false); ReadAttrInt(esite, "group", &dsite.group); ReadAttrTxt(esite, "material", material); ReadAttr(esite, "rgba", 4, dsite.rgba, text); - mjm_setString(dsite.material, material.c_str()); + mjs_setString(dsite.material, material.c_str()); } // joint @@ -2372,8 +2372,8 @@ void mjXReader::OneComposite(XMLElement* elem, mjmBody* pbody, mjmDefault* def) // get element mjmDefault* dspec = &comp.defjoint[(mjtCompKind)kind].back().spec; - mjmJoint& djoint = *dspec->joint; - mjmEquality& dequality = *dspec->equality; + mjsJoint& djoint = *dspec->joint; + mjsEquality& dequality = *dspec->equality; // particle joint if (MapValue(ejnt, "type", &n, joint_map, joint_sz)) { @@ -2414,8 +2414,8 @@ void mjXReader::OneComposite(XMLElement* elem, mjmBody* pbody, mjmDefault* def) comp.add[kind] = true; // get default structs - mjmTendon& dtendon = *comp.def[kind].spec.tendon; - mjmEquality& dequality = *comp.def[kind].spec.equality; + mjsTendon& dtendon = *comp.def[kind].spec.tendon; + mjsEquality& dequality = *comp.def[kind].spec.equality; // solreffix, solimpfix ReadAttr(eten, "solreffix", mjNREF, dequality.solref, text, false, false); @@ -2437,7 +2437,7 @@ void mjXReader::OneComposite(XMLElement* elem, mjmBody* pbody, mjmDefault* def) ReadAttr(eten, "damping", 1, &dtendon.damping, text); ReadAttr(eten, "frictionloss", 1, &dtendon.frictionloss, text); ReadAttrTxt(eten, "material", material); - mjm_setString(dtendon.material, material.c_str()); + mjs_setString(dtendon.material, material.c_str()); ReadAttr(eten, "rgba", 4, dtendon.rgba, text); ReadAttr(eten, "width", 1, &dtendon.width, text); @@ -2473,13 +2473,13 @@ void mjXReader::OneComposite(XMLElement* elem, mjmBody* pbody, mjmDefault* def) // make flexcomp -void mjXReader::OneFlexcomp(XMLElement* elem, mjmBody* pbody) { +void mjXReader::OneFlexcomp(XMLElement* elem, mjsBody* pbody) { string text, material; int n; // create out-of-DOM element mjCFlexcomp fcomp; - mjmFlex& dflex = *fcomp.def.spec.flex; + mjsFlex& dflex = *fcomp.def.spec.flex; // common properties ReadAttrTxt(elem, "name", fcomp.name, true); @@ -2493,7 +2493,7 @@ void mjXReader::OneFlexcomp(XMLElement* elem, mjmBody* pbody) { ReadAttr(elem, "inertiabox", 1, &fcomp.inertiabox, text); fcomp.file = ReadAttrFile(elem, "file", modelfiledir_).value_or(""); if (ReadAttrTxt(elem, "material", material)) { - mjm_setString(dflex.material, material.c_str()); + mjs_setString(dflex.material, material.c_str()); } ReadAttr(elem, "rgba", 4, dflex.rgba, text); if (MapValue(elem, "flatskin", &n, bool_map, 2)) { @@ -2599,16 +2599,16 @@ void mjXReader::OneFlexcomp(XMLElement* elem, mjmBody* pbody) { // add plugin -void mjXReader::OnePlugin(XMLElement* elem, mjmPlugin* plugin) { +void mjXReader::OnePlugin(XMLElement* elem, mjsPlugin* plugin) { plugin->active = true; std::string name = ""; std::string instance_name = ""; ReadAttrTxt(elem, "plugin", name); ReadAttrTxt(elem, "instance", instance_name); - mjm_setString(plugin->name, name.c_str()); - mjm_setString(plugin->instance_name, instance_name.c_str()); + mjs_setString(plugin->name, name.c_str()); + mjs_setString(plugin->instance_name, instance_name.c_str()); if (instance_name.empty()) { - plugin->instance = mjm_addPlugin(model)->instance; + plugin->instance = mjs_addPlugin(model)->instance; ReadPluginConfigs(elem, plugin); } else { model->hasImplicitPluginElem = true; @@ -2637,14 +2637,14 @@ void mjXReader::Default(XMLElement* section, int parentid) { } } if (parentid>=0) { - def = mjm_addDefault(model, text.c_str(), parentid, &thisid); + def = mjs_addDefault(model, text.c_str(), parentid, &thisid); if (!def) { throw mjXError(section, "repeated default class name"); } } else { thisid = 0; - def = mjm_getSpecDefault(model); - mjm_setString(def->name, text.c_str()); + def = mjs_getSpecDefault(model); + mjs_setString(def->name, text.c_str()); } // iterate over elements other than nested defaults @@ -2755,10 +2755,10 @@ void mjXReader::Extension(XMLElement* section) { child, "explicit plugin instance must appear before implicit plugin elements"); } string name; - mjmPlugin* p = mjm_addPlugin(model); - mjm_setString(p->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjsPlugin* p = mjs_addPlugin(model); + mjs_setString(p->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); ReadAttrTxt(child, "name", name, /* required = */ true); - mjm_setString(p->name, name.c_str()); + mjs_setString(p->name, name.c_str()); if (!p->name) { throw mjXError(child, "plugin instance must have a name"); } @@ -2773,7 +2773,7 @@ void mjXReader::Extension(XMLElement* section) { elem = NextSiblingElement(elem); } - mjm_setActivePlugins(model, &active_plugins); + mjs_setActivePlugins(model, &active_plugins); } @@ -2794,14 +2794,14 @@ void mjXReader::Custom(XMLElement* section) { // numeric if (name=="numeric") { // create custom - mjmNumeric* pnum = mjm_addNumeric(model); + mjsNumeric* pnum = mjs_addNumeric(model); // write error info - mjm_setString(pnum->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(pnum->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); // read attributes ReadAttrTxt(elem, "name", elname, true); - mjm_setString(pnum->name, elname.c_str()); + mjs_setString(pnum->name, elname.c_str()); if (ReadAttrInt(elem, "size", &pnum->size)) { int sz = pnum->size < 500 ? pnum->size : 500; for (int i=0; idata, data, pnum->size); + mjs_setDouble(pnum->data, data, pnum->size); } // text else if (name=="text") { // create custom - mjmText* pte = mjm_addText(model); + mjsText* pte = mjs_addText(model); // write error info - mjm_setString(pte->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(pte->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); // read attributes ReadAttrTxt(elem, "name", elname, true); - mjm_setString(pte->name, elname.c_str()); + mjs_setString(pte->name, elname.c_str()); ReadAttrTxt(elem, "data", text, true); if (text.empty()) { throw mjXError(elem, "text field cannot be empty"); } // copy data - mjm_setString(pte->data, text.c_str()); + mjs_setString(pte->data, text.c_str()); } // tuple else if (name=="tuple") { // create custom - mjmTuple* ptu = mjm_addTuple(model); + mjsTuple* ptu = mjs_addTuple(model); // write error info - mjm_setString(ptu->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(ptu->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); // read attributes ReadAttrTxt(elem, "name", elname, true); - mjm_setString(ptu->name, elname.c_str()); + mjs_setString(ptu->name, elname.c_str()); // read objects and add XMLElement* obj = FirstChildElement(elem); @@ -2888,9 +2888,9 @@ void mjXReader::Custom(XMLElement* section) { obj = NextSiblingElement(obj); } - mjm_setInt(ptu->objtype, objtype.data(), objtype.size()); - mjm_setStringVec(ptu->objname, objname.c_str()); - mjm_setDouble(ptu->objprm, objprm.data(), objprm.size()); + mjs_setInt(ptu->objtype, objtype.data(), objtype.size()); + mjs_setStringVec(ptu->objname, objname.c_str()); + mjs_setDouble(ptu->objprm, objprm.data(), objprm.size()); } // advance to next element @@ -3046,30 +3046,30 @@ void mjXReader::Asset(XMLElement* section) { // get class if specified, otherwise use default0 mjmDefault* def = GetClass(elem); if (!def) { - def = mjm_getSpecDefault(model); + def = mjs_getSpecDefault(model); } // texture sub-element if (name=="texture") { // create texture - mjmTexture* ptex = mjm_addTexture(model); + mjsTexture* ptex = mjs_addTexture(model); // write error info - mjm_setString(ptex->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(ptex->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); // read attributes if (MapValue(elem, "type", &n, texture_map, texture_sz)) { ptex->type = (mjtTexture)n; } if (ReadAttrTxt(elem, "name", texname)) { - mjm_setString(ptex->name, texname.c_str()); + mjs_setString(ptex->name, texname.c_str()); } if (ReadAttrTxt(elem, "content_type", content_type)) { - mjm_setString(ptex->content_type, content_type.c_str()); + mjs_setString(ptex->content_type, content_type.c_str()); } auto file = ReadAttrFile(elem, "file", TextureDir()); if (file.has_value()) { - mjm_setString(ptex->file, file->c_str()); + mjs_setString(ptex->file, file->c_str()); } ReadAttrInt(elem, "width", &ptex->width); ReadAttrInt(elem, "height", &ptex->height); @@ -3113,50 +3113,50 @@ void mjXReader::Asset(XMLElement* section) { cubefiles[4] = ReadAttrFile(elem, "filefront", TextureDir()).value_or(""); cubefiles[5] = ReadAttrFile(elem, "fileback", TextureDir()).value_or(""); for (int i = 0; i < cubefiles.size(); i++) { - mjm_setInStringVec(ptex->cubefiles, i, cubefiles[i].c_str()); + mjs_setInStringVec(ptex->cubefiles, i, cubefiles[i].c_str()); } } // material sub-element else if (name=="material") { // create material and parse - mjmMaterial* pmat = mjm_addMaterial(model, def); + mjsMaterial* pmat = mjs_addMaterial(model, def); OneMaterial(elem, pmat); } // mesh sub-element else if (name=="mesh") { // create mesh and parse - mjmMesh* pmesh = mjm_addMesh(model, def); + mjsMesh* pmesh = mjs_addMesh(model, def); OneMesh(elem, pmesh); } // skin sub-element... deprecate ??? else if (name=="skin") { // create skin and parse - mjmSkin* pskin = mjm_addSkin(model); + mjsSkin* pskin = mjs_addSkin(model); OneSkin(elem, pskin); } // hfield sub-element else if (name=="hfield") { // create hfield - mjmHField* phf = mjm_addHField(model); + mjsHField* phf = mjs_addHField(model); // write error info - mjm_setString(phf->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(phf->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); // read attributes string name, content_type; if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(phf->name, name.c_str()); + mjs_setString(phf->name, name.c_str()); } if (ReadAttrTxt(elem, "content_type", content_type)) { - mjm_setString(phf->content_type, content_type.c_str()); + mjs_setString(phf->content_type, content_type.c_str()); } auto file = ReadAttrFile(elem, "file", AssetDir()); if (file.has_value()) { - mjm_setString(phf->file, file->c_str()); + mjs_setString(phf->file, file->c_str()); } ReadAttrInt(elem, "nrow", &phf->nrow); ReadAttrInt(elem, "ncol", &phf->ncol); @@ -3185,13 +3185,13 @@ void mjXReader::Asset(XMLElement* section) { } } - mjm_setFloat(phf->userdata, flipped.data(), flipped.size()); + mjs_setFloat(phf->userdata, flipped.data(), flipped.size()); } // user data not given, set to 0 else { std::vector zero(nrow*ncol); - mjm_setFloat(phf->userdata, zero.data(), zero.size()); + mjs_setFloat(phf->userdata, zero.data(), zero.size()); } } } @@ -3204,7 +3204,7 @@ void mjXReader::Asset(XMLElement* section) { // body/world section parser; recursive -void mjXReader::Body(XMLElement* section, mjmBody* pbody, mjmFrame* frame) { +void mjXReader::Body(XMLElement* section, mjsBody* pbody, mjsFrame* frame) { string text, name; XMLElement* elem; int n; @@ -3215,7 +3215,7 @@ void mjXReader::Body(XMLElement* section, mjmBody* pbody, mjmFrame* frame) { } // no attributes allowed in world body - if (mjm_getId(pbody->element)==0 && section->FirstAttribute() && !frame) { + if (mjs_getId(pbody->element)==0 && section->FirstAttribute() && !frame) { throw mjXError(section, "World body cannot have attributes"); } @@ -3228,13 +3228,13 @@ void mjXReader::Body(XMLElement* section, mjmBody* pbody, mjmFrame* frame) { // get class if specified, otherwise use body mjmDefault* def = GetClass(elem); if (!def) { - def = mjm_getDefault(frame ? frame->element : pbody->element); + def = mjs_getDefault(frame ? frame->element : pbody->element); } // inertial sub-element if (name=="inertial") { // no inertia allowed in world body - if (mjm_getId(pbody->element)==0) { + if (mjs_getId(pbody->element)==0) { throw mjXError(elem, "World body cannot have inertia"); } pbody->explicitinertial = true; @@ -3252,34 +3252,34 @@ void mjXReader::Body(XMLElement* section, mjmBody* pbody, mjmFrame* frame) { // joint sub-element else if (name=="joint") { // no joints allowed in world body - if (mjm_getId(pbody->element)==0) { + if (mjs_getId(pbody->element)==0) { throw mjXError(elem, "World body cannot have joints"); } // create joint and parse - mjmJoint* pjoint = mjm_addJoint(pbody, def); + mjsJoint* pjoint = mjs_addJoint(pbody, def); OneJoint(elem, pjoint); - mjm_setFrame(pjoint->element, frame); + mjs_setFrame(pjoint->element, frame); } // freejoint sub-element else if (name=="freejoint") { // no joints allowed in world body - if (mjm_getId(pbody->element)==0) { + if (mjs_getId(pbody->element)==0) { throw mjXError(elem, "World body cannot have joints"); } // create free joint without defaults - mjmJoint* pjoint = mjm_addFreeJoint(pbody); - mjm_setFrame(pjoint->element, frame); + mjsJoint* pjoint = mjs_addFreeJoint(pbody); + mjs_setFrame(pjoint->element, frame); // save defaults after creation, to make sure writing is ok - mjm_setDefault(pjoint->element, def); + mjs_setDefault(pjoint->element, def); // read attributes std::string name; if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(pjoint->name, name.c_str()); + mjs_setString(pjoint->name, name.c_str()); } ReadAttrInt(elem, "group", &pjoint->group); } @@ -3287,33 +3287,33 @@ void mjXReader::Body(XMLElement* section, mjmBody* pbody, mjmFrame* frame) { // geom sub-element else if (name=="geom") { // create geom and parse - mjmGeom* pgeom = mjm_addGeom(pbody, def); + mjsGeom* pgeom = mjs_addGeom(pbody, def); OneGeom(elem, pgeom); - mjm_setFrame(pgeom->element, frame); + mjs_setFrame(pgeom->element, frame); } // site sub-element else if (name=="site") { // create site and parse - mjmSite* site = mjm_addSite(pbody, def); + mjsSite* site = mjs_addSite(pbody, def); OneSite(elem, site); - mjm_setFrame(site->element, frame); + mjs_setFrame(site->element, frame); } // camera sub-element else if (name=="camera") { // create camera and parse - mjmCamera* pcam = mjm_addCamera(pbody, def); + mjsCamera* pcam = mjs_addCamera(pbody, def); OneCamera(elem, pcam); - mjm_setFrame(pcam->element, frame); + mjs_setFrame(pcam->element, frame); } // light sub-element else if (name=="light") { // create light and parse - mjmLight* plight = mjm_addLight(pbody, def); + mjsLight* plight = mjs_addLight(pbody, def); OneLight(elem, plight); - mjm_setFrame(plight->element, frame); + mjs_setFrame(plight->element, frame); } // plugin sub-element @@ -3338,25 +3338,25 @@ void mjXReader::Body(XMLElement* section, mjmBody* pbody, mjmFrame* frame) { // read childdef mjmDefault* childdef = 0; if (ReadAttrTxt(elem, "childclass", text)) { - childdef = mjm_findDefault(model, text.c_str()); - mjm_findDefault(model, text.c_str()); + childdef = mjs_findDefault(model, text.c_str()); + mjs_findDefault(model, text.c_str()); if (!childdef) { throw mjXError(elem, "unknown default childclass"); } } // create frame - mjmFrame* pframe = mjm_addFrame(pbody, frame); - mjm_setString(pframe->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); - mjm_setDefault(pframe->element, childdef ? childdef : def); + mjsFrame* pframe = mjs_addFrame(pbody, frame); + mjs_setString(pframe->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setDefault(pframe->element, childdef ? childdef : def); // read attributes std::string name, childclass; if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(pframe->name, name.c_str()); + mjs_setString(pframe->name, name.c_str()); } if (ReadAttrTxt(elem, "childclass", childclass)) { - mjm_setString(pframe->childclass, childclass.c_str()); + mjs_setString(pframe->childclass, childclass.c_str()); } ReadAttr(elem, "pos", 3, pframe->pos, text); ReadQuat(elem, "quat", pframe->quat, text); @@ -3370,25 +3370,25 @@ void mjXReader::Body(XMLElement* section, mjmBody* pbody, mjmFrame* frame) { // read childdef mjmDefault* childdef = 0; if (ReadAttrTxt(elem, "childclass", text)) { - childdef = mjm_findDefault(model, text.c_str()); - mjm_findDefault(model, text.c_str()); + childdef = mjs_findDefault(model, text.c_str()); + mjs_findDefault(model, text.c_str()); if (!childdef) { throw mjXError(elem, "unknown default childclass"); } } // create child body - mjmBody* pchild = mjm_addBody(pbody, childdef); - mjm_setString(pchild->info, + mjsBody* pchild = mjs_addBody(pbody, childdef); + mjs_setString(pchild->info, std::string("line = " + std::to_string(elem->GetLineNum())).c_str()); // read attributes std::string name, childclass; if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(pchild->name, name.c_str()); + mjs_setString(pchild->name, name.c_str()); } if (ReadAttrTxt(elem, "childclass", childclass)) { - mjm_setString(pchild->childclass, childclass.c_str()); + mjs_setString(pchild->childclass, childclass.c_str()); } ReadAttr(elem, "pos", 3, pchild->pos, text); ReadQuat(elem, "quat", pchild->quat, text); @@ -3403,10 +3403,10 @@ void mjXReader::Body(XMLElement* section, mjmBody* pbody, mjmFrame* frame) { // read userdata std::vector userdata; ReadVector(elem, "user", userdata, text); - mjm_setDouble(pchild->userdata, userdata.data(), userdata.size()); + mjs_setDouble(pchild->userdata, userdata.data(), userdata.size()); // add frame - mjm_setFrame(pchild->element, frame); + mjs_setFrame(pchild->element, frame); // make recursive call Body(elem, pchild, nullptr); @@ -3438,32 +3438,32 @@ void mjXReader::Contact(XMLElement* section) { // get class if specified, otherwise use default0 mjmDefault* def = GetClass(elem); if (!def) { - def = mjm_getSpecDefault(model); + def = mjs_getSpecDefault(model); } // geom pair to include if (name=="pair") { // create pair and parse - mjmPair* ppair = mjm_addPair(model, def); + mjsPair* ppair = mjs_addPair(model, def); OnePair(elem, ppair); } // body pair to exclude else if (name=="exclude") { - mjmExclude* pexclude = mjm_addExclude(model); + mjsExclude* pexclude = mjs_addExclude(model); string exname, exbody1, exbody2; // write error info - mjm_setString(pexclude->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(pexclude->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); // read name and body names if (ReadAttrTxt(elem, "name", exname)) { - mjm_setString(pexclude->name, exname.c_str()); + mjs_setString(pexclude->name, exname.c_str()); } ReadAttrTxt(elem, "body1", exbody1, true); - mjm_setString(pexclude->bodyname1, exbody1.c_str()); + mjs_setString(pexclude->bodyname1, exbody1.c_str()); ReadAttrTxt(elem, "body2", exbody2, true); - mjm_setString(pexclude->bodyname2, exbody2.c_str()); + mjs_setString(pexclude->bodyname2, exbody2.c_str()); } // advance to next element @@ -3483,11 +3483,11 @@ void mjXReader::Equality(XMLElement* section) { // get class if specified, otherwise use default0 mjmDefault* def = GetClass(elem); if (!def) { - def = mjm_getSpecDefault(model); + def = mjs_getSpecDefault(model); } // create equality constraint and parse - mjmEquality* pequality = mjm_addEquality(model, def); + mjsEquality* pequality = mjs_addEquality(model, def); OneEquality(elem, pequality); // advance to next element @@ -3511,20 +3511,20 @@ void mjXReader::Deformable(XMLElement* section) { // get class if specified, otherwise use default0 mjmDefault* def = GetClass(elem); if (!def) { - def = mjm_getSpecDefault(model); + def = mjs_getSpecDefault(model); } // flex sub-element if (name=="flex") { // create flex and parse - mjmFlex* pflex = mjm_addFlex(model); + mjsFlex* pflex = mjs_addFlex(model); OneFlex(elem, pflex); } // skin sub-element else if (name=="skin") { // create skin and parse - mjmSkin* pskin = mjm_addSkin(model); + mjsSkin* pskin = mjs_addSkin(model); OneSkin(elem, pskin); } @@ -3547,11 +3547,11 @@ void mjXReader::Tendon(XMLElement* section) { // get class if specified, otherwise use default0 mjmDefault* def = GetClass(elem); if (!def) { - def = mjm_getSpecDefault(model); + def = mjs_getSpecDefault(model); } // create equality constraint and parse - mjmTendon* pten = mjm_addTendon(model, def); + mjsTendon* pten = mjs_addTendon(model, def); OneTendon(elem, pten); // process wrap sub-elements @@ -3559,12 +3559,12 @@ void mjXReader::Tendon(XMLElement* section) { while (sub) { // get wrap type string wrap = sub->Value(); - mjmWrap* pwrap;; + mjsWrap* pwrap;; // read attributes depending on type if (wrap=="site") { ReadAttrTxt(sub, "site", text, true); - pwrap = mjm_wrapSite(pten, text.c_str()); + pwrap = mjs_wrapSite(pten, text.c_str()); } else if (wrap=="geom") { @@ -3572,25 +3572,25 @@ void mjXReader::Tendon(XMLElement* section) { if (!ReadAttrTxt(sub, "sidesite", text1)) { text1.clear(); } - pwrap = mjm_wrapGeom(pten, text.c_str(), text1.c_str()); + pwrap = mjs_wrapGeom(pten, text.c_str(), text1.c_str()); } else if (wrap=="pulley") { ReadAttr(sub, "divisor", 1, &data, text, true); - pwrap = mjm_wrapPulley(pten, data); + pwrap = mjs_wrapPulley(pten, data); } else if (wrap=="joint") { ReadAttrTxt(sub, "joint", text, true); ReadAttr(sub, "coef", 1, &data, text1, true); - pwrap = mjm_wrapJoint(pten, text.c_str(), data); + pwrap = mjs_wrapJoint(pten, text.c_str(), data); } else { throw mjXError(sub, "unknown wrap type"); // SHOULD NOT OCCUR } - mjm_setString(pwrap->info, ("line = " + std::to_string(sub->GetLineNum())).c_str()); + mjs_setString(pwrap->info, ("line = " + std::to_string(sub->GetLineNum())).c_str()); // advance to next sub-element sub = NextSiblingElement(sub); @@ -3613,11 +3613,11 @@ void mjXReader::Actuator(XMLElement* section) { // get class if specified, otherwise use default0 mjmDefault* def = GetClass(elem); if (!def) { - def = mjm_getSpecDefault(model); + def = mjs_getSpecDefault(model); } // create actuator and parse - mjmActuator* pact = mjm_addActuator(model, def); + mjsActuator* pact = mjs_addActuator(model, def); OneActuator(elem, pact); // advance to next element @@ -3633,19 +3633,19 @@ void mjXReader::Sensor(XMLElement* section) { XMLElement* elem = FirstChildElement(section); while (elem) { // create sensor, get string type - mjmSensor* psen = mjm_addSensor(model); + mjsSensor* psen = mjs_addSensor(model); string type = elem->Value(); string text, name, objname, refname; std::vector userdata; // read name, noise, userdata if (ReadAttrTxt(elem, "name", name)) { - mjm_setString(psen->name, name.c_str()); + mjs_setString(psen->name, name.c_str()); } ReadAttr(elem, "cutoff", 1, &psen->cutoff, text); ReadAttr(elem, "noise", 1, &psen->noise, text); if (ReadVector(elem, "user", userdata, text)) { - mjm_setDouble(psen->userdata, userdata.data(), userdata.size()); + mjs_setDouble(psen->userdata, userdata.data(), userdata.size()); } // common robotic sensors, attached to a site @@ -3921,15 +3921,15 @@ void mjXReader::Sensor(XMLElement* section) { } if (!objname.empty()) { - mjm_setString(psen->objname, objname.c_str()); + mjs_setString(psen->objname, objname.c_str()); } if (!refname.empty()) { - mjm_setString(psen->refname, refname.c_str()); + mjs_setString(psen->refname, refname.c_str()); } // write info - mjm_setString(psen->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); + mjs_setString(psen->info, ("line = " + std::to_string(elem->GetLineNum())).c_str()); // advance to next element elem = NextSiblingElement(elem); @@ -3950,47 +3950,47 @@ void mjXReader::Keyframe(XMLElement* section) { string text, name = ""; // add keyframe - mjmKey* pk = mjm_addKey(model); + mjsKey* pk = mjs_addKey(model); // read name, time ReadAttrTxt(elem, "name", name); - mjm_setString(pk->name, name.c_str()); + mjs_setString(pk->name, name.c_str()); ReadAttr(elem, "time", 1, &pk->time, text); // read qpos n = ReadAttr(elem, "qpos", 1000, data, text, false, false); if (n) { - mjm_setDouble(pk->qpos, data, n); + mjs_setDouble(pk->qpos, data, n); } // read qvel n = ReadAttr(elem, "qvel", 1000, data, text, false, false); if (n) { - mjm_setDouble(pk->qvel, data, n); + mjs_setDouble(pk->qvel, data, n); } // read act n = ReadAttr(elem, "act", 1000, data, text, false, false); if (n) { - mjm_setDouble(pk->act, data, n); + mjs_setDouble(pk->act, data, n); } // read mpos n = ReadAttr(elem, "mpos", 1000, data, text, false, false); if (n) { - mjm_setDouble(pk->mpos, data, n); + mjs_setDouble(pk->mpos, data, n); } // read mquat n = ReadAttr(elem, "mquat", 1000, data, text, false, false); if (n) { - mjm_setDouble(pk->mquat, data, n); + mjs_setDouble(pk->mquat, data, n); } // read ctrl n = ReadAttr(elem, "ctrl", 1000, data, text, false, false); if (n) { - mjm_setDouble(pk->ctrl, data, n); + mjs_setDouble(pk->ctrl, data, n); } // advance to next element @@ -4006,7 +4006,7 @@ mjmDefault* mjXReader::GetClass(XMLElement* section) { mjmDefault* def = nullptr; if (ReadAttrTxt(section, "class", text)) { - def = mjm_findDefault(model, text.c_str()); + def = mjs_findDefault(model, text.c_str()); if (!def) { throw mjXError( section, diff --git a/src/xml/xml_native_reader.h b/src/xml/xml_native_reader.h index 2d2c177d..50d28a9a 100644 --- a/src/xml/xml_native_reader.h +++ b/src/xml/xml_native_reader.h @@ -54,8 +54,8 @@ class mjXReader : public mjXBase { void Visual(tinyxml2::XMLElement* section); // visual section void Statistic(tinyxml2::XMLElement* section); // statistic section void Asset(tinyxml2::XMLElement* section); // asset section - void Body(tinyxml2::XMLElement* section, mjmBody* pbody, - mjmFrame* pframe); // body/world section + void Body(tinyxml2::XMLElement* section, mjsBody* pbody, + mjsFrame* pframe); // body/world section void Contact(tinyxml2::XMLElement* section); // contact section void Deformable(tinyxml2::XMLElement* section); // deformable section void Equality(tinyxml2::XMLElement* section); // equality section @@ -65,22 +65,22 @@ class mjXReader : public mjXBase { void Keyframe(tinyxml2::XMLElement* section); // keyframe section // single element parsers, used in defaults and main body - void OneFlex(tinyxml2::XMLElement* elem, mjmFlex* pflex); - void OneMesh(tinyxml2::XMLElement* elem, mjmMesh* pmesh); - void OneSkin(tinyxml2::XMLElement* elem, mjmSkin* pskin); - void OneMaterial(tinyxml2::XMLElement* elem, mjmMaterial* pmaterial); - void OneJoint(tinyxml2::XMLElement* elem, mjmJoint* pjoint); - void OneGeom(tinyxml2::XMLElement* elem, mjmGeom* pgeom); - void OneSite(tinyxml2::XMLElement* elem, mjmSite* site); - void OneCamera(tinyxml2::XMLElement* elem, mjmCamera* pcamera); - void OneLight(tinyxml2::XMLElement* elem, mjmLight* plight); - void OnePair(tinyxml2::XMLElement* elem, mjmPair* ppair); - void OneEquality(tinyxml2::XMLElement* elem, mjmEquality* pequality); - void OneTendon(tinyxml2::XMLElement* elem, mjmTendon* ptendon); - void OneActuator(tinyxml2::XMLElement* elem, mjmActuator* pactuator); - void OneComposite(tinyxml2::XMLElement* elem, mjmBody* pbody, mjmDefault* def); - void OneFlexcomp(tinyxml2::XMLElement* elem, mjmBody* pbody); - void OnePlugin(tinyxml2::XMLElement* elem, mjmPlugin* plugin); + void OneFlex(tinyxml2::XMLElement* elem, mjsFlex* pflex); + void OneMesh(tinyxml2::XMLElement* elem, mjsMesh* pmesh); + void OneSkin(tinyxml2::XMLElement* elem, mjsSkin* pskin); + void OneMaterial(tinyxml2::XMLElement* elem, mjsMaterial* pmaterial); + void OneJoint(tinyxml2::XMLElement* elem, mjsJoint* pjoint); + void OneGeom(tinyxml2::XMLElement* elem, mjsGeom* pgeom); + void OneSite(tinyxml2::XMLElement* elem, mjsSite* site); + void OneCamera(tinyxml2::XMLElement* elem, mjsCamera* pcamera); + void OneLight(tinyxml2::XMLElement* elem, mjsLight* plight); + void OnePair(tinyxml2::XMLElement* elem, mjsPair* ppair); + void OneEquality(tinyxml2::XMLElement* elem, mjsEquality* pequality); + void OneTendon(tinyxml2::XMLElement* elem, mjsTendon* ptendon); + void OneActuator(tinyxml2::XMLElement* elem, mjsActuator* pactuator); + void OneComposite(tinyxml2::XMLElement* elem, mjsBody* pbody, mjmDefault* def); + void OneFlexcomp(tinyxml2::XMLElement* elem, mjsBody* pbody); + void OnePlugin(tinyxml2::XMLElement* elem, mjsPlugin* plugin); mjXSchema schema; // schema used for validation mjmDefault* GetClass(tinyxml2::XMLElement* section); // get default class name diff --git a/src/xml/xml_native_writer.cc b/src/xml/xml_native_writer.cc index c0d72f80..642a96d4 100644 --- a/src/xml/xml_native_writer.cc +++ b/src/xml/xml_native_writer.cc @@ -553,33 +553,33 @@ void mjXWriter::OneEquality(XMLElement* elem, mjCEquality* peq, mjCDef* def) { switch (peq->type) { case mjEQ_CONNECT: - WriteAttrTxt(elem, "body1", mjm_getString(peq->name1)); - WriteAttrTxt(elem, "body2", mjm_getString(peq->name2)); + WriteAttrTxt(elem, "body1", mjs_getString(peq->name1)); + WriteAttrTxt(elem, "body2", mjs_getString(peq->name2)); WriteAttr(elem, "anchor", 3, peq->data); break; case mjEQ_WELD: - WriteAttrTxt(elem, "body1", mjm_getString(peq->name1)); - WriteAttrTxt(elem, "body2", mjm_getString(peq->name2)); + WriteAttrTxt(elem, "body1", mjs_getString(peq->name1)); + WriteAttrTxt(elem, "body2", mjs_getString(peq->name2)); WriteAttr(elem, "anchor", 3, peq->data); WriteAttr(elem, "torquescale", 1, peq->data+10); WriteAttr(elem, "relpose", 7, peq->data+3); break; case mjEQ_JOINT: - WriteAttrTxt(elem, "joint1", mjm_getString(peq->name1)); - WriteAttrTxt(elem, "joint2", mjm_getString(peq->name2)); + WriteAttrTxt(elem, "joint1", mjs_getString(peq->name1)); + WriteAttrTxt(elem, "joint2", mjs_getString(peq->name2)); WriteAttr(elem, "polycoef", 5, peq->data); break; case mjEQ_TENDON: - WriteAttrTxt(elem, "tendon1", mjm_getString(peq->name1)); - WriteAttrTxt(elem, "tendon2", mjm_getString(peq->name2)); + WriteAttrTxt(elem, "tendon1", mjs_getString(peq->name1)); + WriteAttrTxt(elem, "tendon2", mjs_getString(peq->name2)); WriteAttr(elem, "polycoef", 5, peq->data); break; case mjEQ_FLEX: - WriteAttrTxt(elem, "flex", mjm_getString(peq->name1)); + WriteAttrTxt(elem, "flex", mjs_getString(peq->name1)); break; default: @@ -731,9 +731,9 @@ void mjXWriter::OneActuator(XMLElement* elem, mjCActuator* pact, mjCDef* def) { // write plugin -void mjXWriter::OnePlugin(XMLElement* elem, mjmPlugin* plugin) { - const std::string instance_name = std::string(mjm_getString(plugin->instance_name)); - const std::string plugin_name = std::string(mjm_getString(plugin->name)); +void mjXWriter::OnePlugin(XMLElement* elem, mjsPlugin* plugin) { + const std::string instance_name = std::string(mjs_getString(plugin->instance_name)); + const std::string plugin_name = std::string(mjs_getString(plugin->name)); if (!instance_name.empty()) { WriteAttrTxt(elem, "instance", instance_name); } else { @@ -783,13 +783,13 @@ string mjXWriter::Write(char *error, size_t error_sz) { // create document and root XMLDocument doc; XMLElement* root = doc.NewElement("mujoco"); - root->SetAttribute("model", mjm_getString(model->modelname)); + root->SetAttribute("model", mjs_getString(model->modelname)); // insert root doc.InsertFirstChild(root); // write comment if present - string text = mjm_getString(model->comment); + string text = mjs_getString(model->comment); if (!text.empty()) { XMLComment* comment = doc.NewComment(text.c_str()); root->LinkEndChild(comment); diff --git a/src/xml/xml_native_writer.h b/src/xml/xml_native_writer.h index 0a475448..0e7513bb 100644 --- a/src/xml/xml_native_writer.h +++ b/src/xml/xml_native_writer.h @@ -72,7 +72,7 @@ class mjXWriter : public mjXBase { void OneEquality(tinyxml2::XMLElement* elem, mjCEquality* pequality, mjCDef* def); void OneTendon(tinyxml2::XMLElement* elem, mjCTendon* ptendon, mjCDef* def); void OneActuator(tinyxml2::XMLElement* elem, mjCActuator* pactuator, mjCDef* def); - void OnePlugin(tinyxml2::XMLElement* elem, mjmPlugin* plugin); + void OnePlugin(tinyxml2::XMLElement* elem, mjsPlugin* plugin); bool writingdefaults; // true during defaults write }; diff --git a/src/xml/xml_urdf.cc b/src/xml/xml_urdf.cc index 23bd2647..28e76beb 100644 --- a/src/xml/xml_urdf.cc +++ b/src/xml/xml_urdf.cc @@ -112,7 +112,7 @@ void mjXURDF::Parse( // get model name std::string modelname; if (ReadAttrTxt(root, "name", modelname)) { - mjm_setString(model->modelname, modelname.c_str()); + mjs_setString(model->modelname, modelname.c_str()); } // find and register all materials @@ -206,16 +206,16 @@ void mjXURDF::Parse( // override the pose for the base link and add a free joint for (int i = 0; i < (int)urName.size(); i++) { if (urParent[i] < 0) { - mjmBody* world = mjm_findBody(model, "world"); - mjmBody* pbody = mjm_findChild(world, urName[i].c_str()); + mjsBody* world = mjs_findBody(model, "world"); + mjsBody* pbody = mjs_findChild(world, urName[i].c_str()); mjuu_copyvec(pbody->pos, pos, 3); mjuu_copyvec(pbody->quat, quat, 4); // add a free joint to allow motion of the body // if the mass is 0, assume the object is static if (!static_body && pbody->mass > 0) { - mjmJoint* pjoint = mjm_addJoint(pbody, 0); - mjm_setString(pjoint->name, (urName[i] + "_free_joint").c_str()); + mjsJoint* pjoint = mjs_addJoint(pbody, 0); + mjs_setString(pjoint->name, (urName[i] + "_free_joint").c_str()); pjoint->type = mjJNT_FREE; } } @@ -226,14 +226,14 @@ void mjXURDF::Parse( void mjXURDF::Body(XMLElement* body_elem) { std::string name, text; XMLElement *elem, *temp, *temp1; - mjmBody *pbody, *world; - mjmGeom* pgeom; + mjsBody *pbody, *world; + mjsGeom* pgeom; - // get body name and pointer to mjmBody + // get body name and pointer to mjsBody ReadAttrTxt(body_elem, "name", name, true); name = GetPrefixedName(name); - world = mjm_findBody(model, "world"); - pbody = mjm_findChild(world, name.c_str()); + world = mjs_findBody(model, "world"); + pbody = mjs_findChild(world, name.c_str()); if (!pbody) { throw mjXError(body_elem, "URDF body not found"); // SHOULD NOT OCCUR } @@ -272,7 +272,7 @@ void mjXURDF::Body(XMLElement* body_elem) { // lquat = rotation from specified to default (joint/body) inertial frame double lquat[4] = {1, 0, 0, 0}; double tmpquat[4] = {1, 0, 0, 0}; - const char* altres = mjm_setFullInertia(pbody, lquat, pbody->inertia); + const char* altres = mjs_setFullInertia(pbody, lquat, pbody->inertia); // inertia are sometimes 0 in URDF files: ignore error in altres, fix later (void) altres; @@ -326,7 +326,7 @@ void mjXURDF::Body(XMLElement* body_elem) { mjXUtil::ReadAttrTxt(elem, "name", geom_name); name = GetPrefixedName(name); if (urGeomNames.find(geom_name) == urGeomNames.end()) { - mjm_setString(pgeom->name, geom_name.c_str()); + mjs_setString(pgeom->name, geom_name.c_str()); urGeomNames.insert(geom_name); } else { std::cerr << "WARNING: Geom with duplicate name '" << geom_name @@ -349,7 +349,7 @@ void mjXURDF::Body(XMLElement* body_elem) { mjXUtil::ReadAttrTxt(elem, "name", geom_name); geom_name = GetPrefixedName(geom_name); if (urGeomNames.find(geom_name) == urGeomNames.end()) { - mjm_setString(pgeom->name, geom_name.c_str()); + mjs_setString(pgeom->name, geom_name.c_str()); urGeomNames.insert(geom_name); } else { std::cerr << "WARNING: Geom with duplicate name '" << geom_name @@ -374,8 +374,8 @@ void mjXURDF::Parse(XMLElement* root) { void mjXURDF::Joint(XMLElement* joint_elem) { std::string jntname, name, text; XMLElement *elem; - mjmBody *pbody, *parent, *world; - mjmJoint *pjoint=0, *pjoint1=0, *pjoint2=0; + mjsBody *pbody, *parent, *world; + mjsJoint *pjoint=0, *pjoint1=0, *pjoint2=0; int jointtype; // get type and name @@ -390,8 +390,8 @@ void mjXURDF::Joint(XMLElement* joint_elem) { elem = FindSubElem(joint_elem, "parent", true); ReadAttrTxt(elem, "link", name, true); name = GetPrefixedName(name); - world = mjm_findBody(model, "world"); - parent = mjm_findChild(world, name.c_str()); + world = mjs_findBody(model, "world"); + parent = mjs_findChild(world, name.c_str()); if (!parent) { // SHOULD NOT OCCUR throw mjXError(elem, "invalid parent name in URDF joint definition"); } @@ -400,8 +400,8 @@ void mjXURDF::Joint(XMLElement* joint_elem) { elem = FindSubElem(joint_elem, "child", true); ReadAttrTxt(elem, "link", name, true); name = GetPrefixedName(name); - world = mjm_findBody(model, "world"); - pbody = mjm_findChild(world, name.c_str()); + world = mjs_findBody(model, "world"); + pbody = mjs_findChild(world, name.c_str()); if (!pbody) { // SHOULD NOT OCCUR throw mjXError(elem, "invalid child name in URDF joint definition"); } @@ -418,16 +418,16 @@ void mjXURDF::Joint(XMLElement* joint_elem) { switch (jointtype) { case 0: // revolute case 1: // continuous - pjoint = mjm_addJoint(pbody, 0); - mjm_setString(pjoint->name, jntname.c_str()); + pjoint = mjs_addJoint(pbody, 0); + mjs_setString(pjoint->name, jntname.c_str()); pjoint->type = mjJNT_HINGE; mjuu_setvec(pjoint->pos, 0, 0, 0); mjuu_copyvec(pjoint->axis, axis, 3); break; case 2: // prismatic - pjoint = mjm_addJoint(pbody, 0); - mjm_setString(pjoint->name, jntname.c_str()); + pjoint = mjs_addJoint(pbody, 0); + mjs_setString(pjoint->name, jntname.c_str()); pjoint->type = mjJNT_SLIDE; mjuu_setvec(pjoint->pos, 0, 0, 0); mjuu_copyvec(pjoint->axis, axis, 3); @@ -437,8 +437,8 @@ void mjXURDF::Joint(XMLElement* joint_elem) { return; case 4: // floating - pjoint = mjm_addJoint(pbody, 0); - mjm_setString(pjoint->name, jntname.c_str()); + pjoint = mjs_addJoint(pbody, 0); + mjs_setString(pjoint->name, jntname.c_str()); pjoint->type = mjJNT_FREE; break; @@ -448,8 +448,8 @@ void mjXURDF::Joint(XMLElement* joint_elem) { mjuu_quat2mat(mat, quat); // construct slider along x - pjoint = mjm_addJoint(pbody, 0); - mjm_setString(pjoint->name, (jntname + "_TX").c_str()); + pjoint = mjs_addJoint(pbody, 0); + mjs_setString(pjoint->name, (jntname + "_TX").c_str()); pjoint->type = mjJNT_SLIDE; tmpaxis[0] = mat[0]; tmpaxis[1] = mat[3]; @@ -458,8 +458,8 @@ void mjXURDF::Joint(XMLElement* joint_elem) { mjuu_copyvec(pjoint->axis, tmpaxis, 3); // construct slider along y - pjoint1 = mjm_addJoint(pbody, 0); - mjm_setString(pjoint1->name, (jntname + "_TY").c_str()); + pjoint1 = mjs_addJoint(pbody, 0); + mjs_setString(pjoint1->name, (jntname + "_TY").c_str()); pjoint1->type = mjJNT_SLIDE; tmpaxis[0] = mat[1]; tmpaxis[1] = mat[4]; @@ -468,8 +468,8 @@ void mjXURDF::Joint(XMLElement* joint_elem) { mjuu_copyvec(pjoint1->axis, tmpaxis, 3); // construct hinge around z = locaxis - pjoint2 = mjm_addJoint(pbody, 0); - mjm_setString(pjoint2->name, (jntname + "_RZ").c_str()); + pjoint2 = mjs_addJoint(pbody, 0); + mjs_setString(pjoint2->name, (jntname + "_RZ").c_str()); pjoint2->type = mjJNT_HINGE; mjuu_setvec(pjoint2->pos, 0, 0, 0); mjuu_copyvec(pjoint2->axis, axis, 3); @@ -506,7 +506,7 @@ void mjXURDF::Joint(XMLElement* joint_elem) { // parse origin and geometry elements of visual or collision -mjmGeom* mjXURDF::Geom(XMLElement* geom_elem, mjmBody* pbody, bool collision) { +mjsGeom* mjXURDF::Geom(XMLElement* geom_elem, mjsBody* pbody, bool collision) { XMLElement *elem, *temp; std::string text, meshfile; @@ -514,8 +514,8 @@ mjmGeom* mjXURDF::Geom(XMLElement* geom_elem, mjmBody* pbody, bool collision) { elem = FindSubElem(geom_elem, "geometry", true); // add BOX geom, modify type later - mjmGeom* pgeom = mjm_addGeom(pbody, 0); - mjm_setString(pgeom->name, ""); + mjsGeom* pgeom = mjs_addGeom(pbody, 0); + mjs_setString(pgeom->name, ""); pgeom->type = mjGEOM_BOX; if (collision) { pgeom->contype = 1; @@ -576,19 +576,19 @@ mjmGeom* mjXURDF::Geom(XMLElement* geom_elem, mjmBody* pbody, bool collision) { meshname = mjuu_stripext(meshname); // look for existing mesh - mjmMesh* mesh = mjm_findMesh(model, meshname.c_str()); - mjmMesh* pmesh = 0; + mjsMesh* mesh = mjs_findMesh(model, meshname.c_str()); + mjsMesh* pmesh = 0; // does not exist: create if (!mesh) { - pmesh = mjm_addMesh(model, 0); + pmesh = mjs_addMesh(model, 0); } // exists with different scale: append name with '1', create else if (mesh->scale[0]!=meshscale[0] || mesh->scale[1]!=meshscale[1] || mesh->scale[2]!=meshscale[2]) { - pmesh = mjm_addMesh(model, 0); + pmesh = mjs_addMesh(model, 0); meshname = meshname + "1"; } @@ -598,9 +598,9 @@ mjmGeom* mjXURDF::Geom(XMLElement* geom_elem, mjmBody* pbody, bool collision) { } // set fields - mjm_setString(pmesh->file, meshfile.c_str()); - mjm_setString(pmesh->name, meshname.c_str()); - mjm_setString(pgeom->meshname, meshname.c_str()); + mjs_setString(pmesh->file, meshfile.c_str()); + mjs_setString(pmesh->name, meshname.c_str()); + mjs_setString(pgeom->meshname, meshname.c_str()); pmesh->scale[0] = meshscale[0]; pmesh->scale[1] = meshscale[1]; pmesh->scale[2] = meshscale[2]; @@ -683,22 +683,22 @@ void mjXURDF::AddBody(std::string name) { // add body with given number to the mjCModel tree, process children void mjXURDF::AddToTree(int n) { // get pointer to parent in mjCModel tree - mjmBody *parent = 0, *child = 0, *world = 0; + mjsBody *parent = 0, *child = 0, *world = 0; if (urParent[n]>=0) { - world = mjm_findBody(model, "world"); - parent = mjm_findChild(world, urName[urParent[n]].c_str()); + world = mjs_findBody(model, "world"); + parent = mjs_findChild(world, urName[urParent[n]].c_str()); if (!parent) throw mjXError(0, "URDF body parent should already be in tree: %s", urName[urParent[n]].c_str()); // SHOULD NOT OCCUR } else { - parent = mjm_findBody(model, "world"); + parent = mjs_findBody(model, "world"); } // add this body if (urName[n] != "world") { - child = mjm_addBody(parent, 0); - mjm_setString(child->name, urName[n].c_str()); + child = mjs_addBody(parent, 0); + mjs_setString(child->name, urName[n].c_str()); } // add children recursively diff --git a/src/xml/xml_urdf.h b/src/xml/xml_urdf.h index 79a76dd4..d2efa317 100644 --- a/src/xml/xml_urdf.h +++ b/src/xml/xml_urdf.h @@ -51,8 +51,8 @@ class mjXURDF : public mjXBase { void AddToTree(int n); // add body to mjCModel tree void Body(tinyxml2::XMLElement* body_elem); // parse body void Joint(tinyxml2::XMLElement* joint_elem); // parse joint - mjmGeom* Geom(tinyxml2::XMLElement* geom_elem, - mjmBody* pbody, bool collision); // parse origin and geometry of geom + mjsGeom* Geom(tinyxml2::XMLElement* geom_elem, + mjsBody* pbody, bool collision); // parse origin and geometry of geom void Origin(tinyxml2::XMLElement* origin_elem, double* pos, double* quat); // parse origin element void MakeMaterials(tinyxml2::XMLElement* elem); // find all materials recursively diff --git a/test/user/user_api_test.cc b/test/user/user_api_test.cc index e0a83d5f..74bd22cf 100644 --- a/test/user/user_api_test.cc +++ b/test/user/user_api_test.cc @@ -39,28 +39,28 @@ using ::testing::NotNull; // ----------------------------- test set/get -------------------------------- TEST_F(MujocoTest, ReadWriteData) { - mjSpec* spec = mjm_createSpec(); - mjmBody* world = mjm_findBody(spec, "world"); - mjmBody* body = mjm_addBody(world, 0); - mjmSite* site = mjm_addSite(body, 0); + mjSpec* spec = mjs_createSpec(); + mjsBody* world = mjs_findBody(spec, "world"); + mjsBody* body = mjs_addBody(world, 0); + mjsSite* site = mjs_addSite(body, 0); { double vec[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; const char* str = "sitename"; - mjm_setString(site->name, str); - mjm_setDouble(site->userdata, vec, 10); + mjs_setString(site->name, str); + mjs_setDouble(site->userdata, vec, 10); } - EXPECT_THAT(mjm_getString(site->name), HasSubstr("sitename")); + EXPECT_THAT(mjs_getString(site->name), HasSubstr("sitename")); int nsize; - const double* vec = mjm_getDouble(site->userdata, &nsize); + const double* vec = mjs_getDouble(site->userdata, &nsize); for (int i = 0; i < nsize; ++i) { EXPECT_EQ(vec[i], i); } - mjm_deleteSpec(spec); + mjs_deleteSpec(spec); } // ------------------- test recompilation multiple files ---------------------- @@ -93,12 +93,12 @@ TEST_F(PluginTest, RecompileCompare) { mjSpec* s = mjParseXML(xml.c_str(), nullptr, err.data(), err.size()); // copy spec - mjSpec* s_copy = mjm_copySpec(s); + mjSpec* s_copy = mjs_copySpec(s); // compile twice and compare - mjModel* m_old = mjm_compile(s, nullptr); - mjModel* m_new = mjm_compile(s, nullptr); - mjModel* m_copy = mjm_compile(s_copy, nullptr); + mjModel* m_old = mjs_compile(s, nullptr); + mjModel* m_new = mjs_compile(s, nullptr); + mjModel* m_copy = mjs_compile(s_copy, nullptr); ASSERT_THAT(m_old, NotNull()) << "Failed to compile " << xml << ": " << err.data(); @@ -118,8 +118,8 @@ TEST_F(PluginTest, RecompileCompare) { << "Different field: " << field << '\n'; // copy to a new spec, compile and compare - mjSpec* s_copy2 = mjm_copySpec(s); - mjModel* m_copy2 = mjm_compile(s_copy2, nullptr); + mjSpec* s_copy2 = mjs_copySpec(s); + mjModel* m_copy2 = mjs_compile(s_copy2, nullptr); ASSERT_THAT(m_copy2, NotNull()) << "Failed to compile " << xml << ": " << err.data(); @@ -130,9 +130,9 @@ TEST_F(PluginTest, RecompileCompare) { << "Different field: " << field << '\n'; // delete models - mjm_deleteSpec(s); - mjm_deleteSpec(s_copy); - mjm_deleteSpec(s_copy2); + mjs_deleteSpec(s); + mjs_deleteSpec(s_copy); + mjs_deleteSpec(s_copy2); mj_deleteModel(m_old); mj_deleteModel(m_new); mj_deleteModel(m_copy); @@ -273,7 +273,7 @@ TEST_F(MujocoTest, Attach) { EXPECT_THAT(parent, NotNull()) << er.data(); // get frame - mjmFrame* frame = mjm_findFrame(parent, "frame"); + mjsFrame* frame = mjs_findFrame(parent, "frame"); EXPECT_THAT(frame, NotNull()); // model with one cylinder and a hinge @@ -281,15 +281,15 @@ TEST_F(MujocoTest, Attach) { EXPECT_THAT(child, NotNull()) << er.data(); // get subtree - mjmBody* body = mjm_findBody(child, "body"); + mjsBody* body = mjs_findBody(child, "body"); EXPECT_THAT(body, NotNull()); // attach child to parent frame EXPECT_THAT( - mjm_attachBody(frame, body, /*prefix=*/"attached-", /*suffix=*/"-1"), 0); + mjs_attachBody(frame, body, /*prefix=*/"attached-", /*suffix=*/"-1"), 0); // compile new model - mjModel* m_attached = mjm_compile(parent, 0); + mjModel* m_attached = mjs_compile(parent, 0); EXPECT_THAT(m_attached, NotNull()); // check full name stored in mjModel @@ -306,8 +306,8 @@ TEST_F(MujocoTest, Attach) { << "Different field: " << field << '\n';; // destroy everything - mjm_deleteSpec(parent); - mjm_deleteSpec(child); + mjs_deleteSpec(parent); + mjs_deleteSpec(child); mj_deleteModel(m_attached); mj_deleteModel(m_expected); } From 31d48d3e44af927127b176425ae4a99395ae8149 Mon Sep 17 00:00:00 2001 From: Cong Wang Date: Fri, 22 Mar 2024 16:07:57 +0100 Subject: [PATCH 32/51] Update fluid.rst --- doc/computation/fluid.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/computation/fluid.rst b/doc/computation/fluid.rst index bec587a4..8b049b43 100644 --- a/doc/computation/fluid.rst +++ b/doc/computation/fluid.rst @@ -424,7 +424,7 @@ increasing Reynolds numbers, and a single reference area :math:`A_D` may not be drag for highly irregular or slender bodies. For example, experimental fits are derived from problems ranging from falling playing cards :cite:p:`wang2004,andersen2005a,andersen2005b` to particle transport :cite:p:`loth2008, bagheri2016`. See screen capture of the -`cards.xml `__ model on the right. +`cards.xml `__ model on the right. We derive a formula for :math:`\mathbf{f}_\text{D}` based on two surfaces :math:`A^\text{proj}_\mathbf{v}` and :math:`A_\text{max}`. The first, :math:`A^\text{proj}_\mathbf{v}`, is the cylindrical projection of the body onto a From 2019d42ca67d9eb7e3bb01eacb97ad98f9d0d4f7 Mon Sep 17 00:00:00 2001 From: Baruch Tabanpour Date: Fri, 22 Mar 2024 17:03:44 -0700 Subject: [PATCH 33/51] Small change to testspeed file. PiperOrigin-RevId: 618323795 Change-Id: I3a6307b8ae6d9af0d17c0ae85eae673d60112ddf --- mjx/mujoco/mjx/__init__.py | 1 + mjx/mujoco/mjx/_src/support.py | 1 - mjx/mujoco/mjx/_src/test_util.py | 82 ++++++++++++++++++++ mjx/mujoco/mjx/testspeed.py | 125 ++++++++++--------------------- 4 files changed, 124 insertions(+), 85 deletions(-) diff --git a/mjx/mujoco/mjx/__init__.py b/mjx/mujoco/mjx/__init__.py index e21b14fd..978f44ab 100644 --- a/mjx/mujoco/mjx/__init__.py +++ b/mjx/mujoco/mjx/__init__.py @@ -49,4 +49,5 @@ from mujoco.mjx._src.solver import solve from mujoco.mjx._src.support import full_m from mujoco.mjx._src.support import is_sparse from mujoco.mjx._src.support import mul_m +from mujoco.mjx._src.test_util import benchmark from mujoco.mjx._src.types import * diff --git a/mjx/mujoco/mjx/_src/support.py b/mjx/mujoco/mjx/_src/support.py index 03966fa2..28314def 100644 --- a/mjx/mujoco/mjx/_src/support.py +++ b/mjx/mujoco/mjx/_src/support.py @@ -13,7 +13,6 @@ # limitations under the License. # ============================================================================== """Engine support functions.""" - from typing import Optional, Tuple, Union import jax diff --git a/mjx/mujoco/mjx/_src/test_util.py b/mjx/mujoco/mjx/_src/test_util.py index b360fb63..36d07d9f 100644 --- a/mjx/mujoco/mjx/_src/test_util.py +++ b/mjx/mujoco/mjx/_src/test_util.py @@ -14,14 +14,96 @@ # ============================================================================== """Utilities for testing.""" +import os import sys +import time from typing import Dict, Tuple from xml.etree import ElementTree as ET from etils import epath +import jax import mujoco +# pylint: disable=g-importing-member +from mujoco.mjx._src import forward +from mujoco.mjx._src import io +# pylint: enable=g-importing-member import numpy as np + +def _measure(fn, *args) -> Tuple[float, float]: + """Reports jit time and op time for a function.""" + + beg = time.perf_counter() + compiled_fn = fn.lower(*args).compile() + end = time.perf_counter() + jit_time = end - beg + + beg = time.perf_counter() + result = compiled_fn(*args) + jax.block_until_ready(result) + end = time.perf_counter() + run_time = end - beg + + return jit_time, run_time + + +def benchmark( + m: mujoco.MjModel, + nstep: int = 1000, + batch_size: int = 1024, + unroll_steps: int = 1, + solver: str = 'cg', + iterations: int = 1, + ls_iterations: int = 4, +) -> Tuple[float, float, int]: + """Benchmark a model.""" + + xla_flags = os.environ.get('XLA_FLAGS', '') + xla_flags += ' --xla_gpu_triton_gemm_any=True' + os.environ['XLA_FLAGS'] = xla_flags + + m.opt.solver = { + 'cg': mujoco.mjtSolver.mjSOL_CG, + 'newton': mujoco.mjtSolver.mjSOL_NEWTON, + }[solver.lower()] + m.opt.iterations = iterations + m.opt.ls_iterations = ls_iterations + m = io.put_model(m) + + @jax.pmap + def init(key): + key = jax.random.split(key, batch_size // jax.device_count()) + + @jax.vmap + def random_init(key): + d = io.make_data(m) + qvel = 0.01 * jax.random.normal(key, shape=(m.nv,)) + d = d.replace(qvel=qvel) + return d + + return random_init(key) + + key = jax.random.split(jax.random.key(0), jax.device_count()) + d = init(key) + jax.block_until_ready(d) + + @jax.pmap + def unroll(d): + @jax.vmap + def step(d, _): + d = forward.step(m, d) + return d, None + + d, _ = jax.lax.scan(step, d, None, length=nstep, unroll=unroll_steps) + + return d + + jit_time, run_time = _measure(unroll, d) + steps = nstep * batch_size + + return jit_time, run_time, steps + + _ACTUATOR_TYPES = ['motor', 'velocity', 'position', 'general', 'intvelocity'] _DYN_TYPES = ['none', 'integrator', 'filter', 'filterexact'] _DYN_PRMS = ['0.189', '2.1'] diff --git a/mjx/mujoco/mjx/testspeed.py b/mjx/mujoco/mjx/testspeed.py index d66d475f..686e8cbc 100644 --- a/mjx/mujoco/mjx/testspeed.py +++ b/mjx/mujoco/mjx/testspeed.py @@ -14,110 +14,67 @@ # ============================================================================== """Run benchmarks on various devices.""" -import os -import time -from typing import Sequence, Tuple +from typing import Sequence from absl import app from absl import flags from etils import epath -import jax import mujoco from mujoco import mjx -FLAGS = flags.FLAGS - -flags.DEFINE_string('mjcf', None, 'path to model', required=True) -flags.DEFINE_integer('nstep', 1000, 'number of steps per rollout') -flags.DEFINE_integer('batch_size', 1024, 'number of parallel rollouts') -flags.DEFINE_integer('unroll', 1, 'loop unroll length') -flags.DEFINE_enum('solver', 'cg', ['cg', 'newton'], 'constraint solver') -flags.DEFINE_integer('iterations', 1, 'number of solver iterations') -flags.DEFINE_integer('ls_iterations', 4, 'number of linesearch iterations') -flags.DEFINE_enum('output', 'text', ['text', 'tsv'], 'format to print results') - - -def _measure(fn, *args) -> Tuple[float, float]: - """Reports jit time and op time for a function.""" - - beg = time.perf_counter() - compiled_fn = fn.lower(*args).compile() - end = time.perf_counter() - jit_time = end - beg - - beg = time.perf_counter() - result = compiled_fn(*args) - jax.block_until_ready(result) - end = time.perf_counter() - run_time = end - beg - - return jit_time, run_time +_MJCF = flags.DEFINE_string('mjcf', None, 'path to model', required=True) +_BASE_PATH = flags.DEFINE_string( + 'base_path', None, 'base path, defaults to mujoco.mjx resource path' +) +_NSTEP = flags.DEFINE_integer('nstep', 1000, 'number of steps per rollout') +_BATCH_SIZE = flags.DEFINE_integer( + 'batch_size', 1024, 'number of parallel rollouts' +) +_UNROLL = flags.DEFINE_integer('unroll', 1, 'loop unroll length') +_SOLVER = flags.DEFINE_enum( + 'solver', 'cg', ['cg', 'newton'], 'constraint solver' +) +_ITERATIONS = flags.DEFINE_integer( + 'iterations', 1, 'number of solver iterations' +) +_LS_ITERATIONS = flags.DEFINE_integer( + 'ls_iterations', 4, 'number of linesearch iterations' +) +_OUTPUT = flags.DEFINE_enum( + 'output', 'text', ['text', 'tsv'], 'format to print results' +) def _main(argv: Sequence[str]): - """Benchmark a model.""" - - xla_flags = os.environ.get('XLA_FLAGS', '') - xla_flags += ' --xla_gpu_triton_gemm_any=True' - os.environ['XLA_FLAGS'] = xla_flags - - f = epath.resource_path('mujoco.mjx') / 'test_data' / FLAGS.mjcf + """Runs testpeed function.""" + base_path = _BASE_PATH.value or epath.resource_path('mujoco.mjx') + f = base_path / 'test_data' / _MJCF.value m = mujoco.MjModel.from_xml_path(f.as_posix()) - m.opt.solver = { - 'cg': mujoco.mjtSolver.mjSOL_CG, - 'newton': mujoco.mjtSolver.mjSOL_NEWTON, - }[FLAGS.solver.lower()] - m.opt.iterations = FLAGS.iterations - m.opt.ls_iterations = FLAGS.ls_iterations - m = mjx.put_model(m) - if FLAGS.output == 'text': - print(f"Rolling out {FLAGS.nstep} steps at dt = {m.opt.timestep:.3f}...") + print(f'Rolling out {_NSTEP.value} steps at dt = {m.opt.timestep:.3f}...') + jit_time, run_time, steps = mjx.benchmark( + m, + _NSTEP.value, + _BATCH_SIZE.value, + _UNROLL.value, + _SOLVER.value, + _ITERATIONS.value, + _LS_ITERATIONS.value, + ) - @jax.pmap - def init(key): - key = jax.random.split(key, FLAGS.batch_size // jax.device_count()) - - @jax.vmap - def random_init(key): - d = mjx.make_data(m) - qvel = 0.01 * jax.random.normal(key, shape=(m.nv,)) - d = d.replace(qvel=qvel) - return d - - return random_init(key) - - key = jax.random.split(jax.random.key(0), jax.device_count()) - d = init(key) - jax.block_until_ready(d) - - @jax.pmap - def unroll(d): - - @jax.vmap - def step(d, _): - d = mjx.step(m, d) - return d, None - - d, _ = jax.lax.scan(step, d, None, length=FLAGS.nstep, unroll=FLAGS.unroll) - - return d - - jit_time, run_time = _measure(unroll, d) - steps = FLAGS.nstep * FLAGS.batch_size - - if FLAGS.output == 'text': + name = argv[0] + if _OUTPUT.value == 'text': print(f""" -Summary for {FLAGS.batch_size} parallel rollouts +Summary for {_BATCH_SIZE.value} parallel rollouts Total JIT time: {jit_time:.2f} s Total simulation time: {run_time:.2f} s Total steps per second: { steps / run_time:.0f} Total realtime factor: { steps * m.opt.timestep / run_time:.2f} x Total time per step: { 1e6 * run_time / steps:.2f} µs""") - elif FLAGS.output == 'tsv': - name = argv[0].split('/')[-1].replace('testspeed_', '') - print(f"{name}\tjit: {jit_time:.2f}s\tsteps/second: {steps / run_time:.0f}") + elif _OUTPUT.value == 'tsv': + name = name.split('/')[-1].replace('testspeed_', '') + print(f'{name}\tjit: {jit_time:.2f}s\tsteps/second: {steps / run_time:.0f}') def main(): From bb42ff165739a6ff7ed683cfce342297624d81bd Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Sun, 24 Mar 2024 13:12:24 -0700 Subject: [PATCH 34/51] Fix order of enable flag strings. Before this change, using the UI to toggle the "InvDiscrete" and "Sensornoise" flags would toggle the opposite flag. PiperOrigin-RevId: 618658133 Change-Id: I35d4b9da2fdf68fed24efd518a30af60d3a806eb --- doc/changelog.rst | 5 +++++ src/engine/engine_support.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/doc/changelog.rst b/doc/changelog.rst index e32cd0a5..6c8e2b5a 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -59,6 +59,11 @@ Python bindings .. |ls_colab| image:: https://colab.research.google.com/assets/colab-badge.svg :target: https://colab.research.google.com/github/google-deepmind/mujoco/blob/main/python/least_squares.ipynb +Simulate +^^^^^^^^ +13. Fixed bug in order of enable flag strings. Before this change, using the simulate UI to toggle the + :ref:`invdiscrete` or :ref:`sensornoise` + flags would actually toggle the other flag. Version 3.1.2 (February 05, 2024) ----------------------------------- diff --git a/src/engine/engine_support.c b/src/engine/engine_support.c index 1090305c..c3601931 100644 --- a/src/engine/engine_support.c +++ b/src/engine/engine_support.c @@ -66,8 +66,8 @@ const char* mjENABLESTRING[mjNENABLE] = { "Override", "Energy", "Fwdinv", - "Sensornoise", "InvDiscrete", + "Sensornoise", "MultiCCD", "Island" }; From 7875e93feab37b28e887f6c638f7016ccf7aef40 Mon Sep 17 00:00:00 2001 From: Matthew Bennice Date: Sun, 24 Mar 2024 20:58:08 -0700 Subject: [PATCH 35/51] Improve error text when a mesh face references an invalid vertex. PiperOrigin-RevId: 618715730 Change-Id: I28fae1e1570d359db4be98e9c5b7713169eaf34f --- src/user/user_mesh.cc | 3 ++- test/user/user_mesh_test.cc | 25 +++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/user/user_mesh.cc b/src/user/user_mesh.cc index 71357f45..1bd6f5b4 100644 --- a/src/user/user_mesh.cc +++ b/src/user/user_mesh.cc @@ -549,7 +549,8 @@ void mjCMesh::Compile(const mjVFS* vfs) { // check vertices exist for (int i=0; i= nvert_ || userface_[i] < 0) { - throw mjCError(this, "index in face does not exist in vertex array"); + throw mjCError(this, "in face %d, vertex index %d does not exist", + nullptr, i / 3, userface_[i]); } } diff --git a/test/user/user_mesh_test.cc b/test/user/user_mesh_test.cc index 1eaaa0e1..0fc57317 100644 --- a/test/user/user_mesh_test.cc +++ b/test/user/user_mesh_test.cc @@ -945,6 +945,31 @@ TEST_F(MjCMeshTest, NaNConvexHullDisallowed) { mj_deleteModel(model); } +TEST_F(MjCMeshTest, InvalidIndexInFace) { + static constexpr char xml[] = R"( + + + + + + + + + )"; + std::array error; + mjModel* model = LoadModelFromString(xml, error.data(), error.size()); + ASSERT_THAT(model, IsNull()); + EXPECT_THAT( + error.data(), + HasSubstr( + "in face 0, vertex index 6 does not exist")); + mj_deleteModel(model); +} + + } // namespace } // namespace mujoco From 357ff8bbdc3af7e90250406f0b768921e47d8257 Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Mon, 25 Mar 2024 07:20:01 -0700 Subject: [PATCH 36/51] Remove mjCAlternative and user_objects dependency from xml_urdf. PiperOrigin-RevId: 618832482 Change-Id: I626bb956cd3eb35317811b9b577cc7db128262ea --- src/user/user_api.cc | 8 ++++++ src/user/user_api.h | 7 +++++ src/user/user_flexcomp.cc | 3 ++- src/user/user_flexcomp.h | 2 +- src/user/user_init.cc | 7 +++++ src/user/user_objects.cc | 55 +++++++++++++-------------------------- src/user/user_objects.h | 21 +++------------ src/xml/xml_urdf.cc | 6 ++--- 8 files changed, 50 insertions(+), 59 deletions(-) diff --git a/src/user/user_api.cc b/src/user/user_api.cc index 6af8b3d9..3469f367 100644 --- a/src/user/user_api.cc +++ b/src/user/user_api.cc @@ -498,6 +498,14 @@ void mjs_setFrame(mjElement dest, mjsFrame* frame) { +// Resolve alternative orientations. +const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const char* sequence, + const mjsOrientation* orientation) { + return ResolveOrientation(quat, degree, sequence, *orientation); +} + + + // get id int mjs_getId(mjElement element) { return reinterpret_cast(element)->id; diff --git a/src/user/user_api.h b/src/user/user_api.h index b78c8495..db24d853 100644 --- a/src/user/user_api.h +++ b/src/user/user_api.h @@ -915,6 +915,10 @@ MJAPI void mjs_setDefault(mjElement element, mjmDefault* def); // Set frame. MJAPI void mjs_setFrame(mjElement dest, mjsFrame* frame); +// Resolve alternative orientations to quat. +MJAPI const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const char* sequence, + const mjsOrientation* orientation); + // Compute quat and inertia from body->fullinertia. MJAPI const char* mjs_setFullInertia(mjsBody* body, double quat[4], double inertia[3]); @@ -924,6 +928,9 @@ MJAPI const char* mjs_setFullInertia(mjsBody* body, double quat[4], double inert // Default model attributes. MJAPI void mjs_defaultSpec(mjSpec& model); +// Default orientation attributes. +MJAPI void mjs_defaultOrientation(mjsOrientation& orient); + // Default body attributes. MJAPI void mjs_defaultBody(mjsBody& body); diff --git a/src/user/user_flexcomp.cc b/src/user/user_flexcomp.cc index 41e031e6..3130e39c 100644 --- a/src/user/user_flexcomp.cc +++ b/src/user/user_flexcomp.cc @@ -73,6 +73,7 @@ mjCFlexcomp::mjCFlexcomp(void) { centered = false; mjs_defaultPlugin(plugin); + mjs_defaultOrientation(alt); plugin_name = ""; plugin_instance_name = ""; plugin.name = (mjString)&plugin_name; @@ -131,7 +132,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) { } // compute orientation - const char* alterr = alt.Set(quat, model->spec.degree, model->spec.euler); + const char* alterr = mjs_resolveOrientation(quat, model->spec.degree, model->spec.euler, &alt); if (alterr) { return comperr(error, alterr, error_sz); } diff --git a/src/user/user_flexcomp.h b/src/user/user_flexcomp.h index 8e6b4340..29d72301 100644 --- a/src/user/user_flexcomp.h +++ b/src/user/user_flexcomp.h @@ -79,7 +79,7 @@ class mjCFlexcomp { // pose transform relative to parent body double pos[3]; // position double quat[4]; // orientation - mjCAlternative alt; // alternative orientation + mjsOrientation alt; // alternative orientation // set by user or computed internally bool rigid; // all vertices are in parent body (all pinned) diff --git a/src/user/user_init.cc b/src/user/user_init.cc index 0e85848e..b9553933 100644 --- a/src/user/user_init.cc +++ b/src/user/user_init.cc @@ -75,6 +75,13 @@ void mjs_defaultSpec(mjSpec& model) { +// default orientation attributes +void mjs_defaultOrientation(mjsOrientation& orient) { + orient.axisangle[0] = orient.xyaxes[0] = orient.zaxis[0] = orient.euler[0] = mjNAN; +} + + + // default body attributes void mjs_defaultBody(mjsBody& body) { memset(&body, 0, sizeof(mjsBody)); diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index 79008f69..6b5d41ee 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -141,17 +141,22 @@ mjCError::mjCError(const mjCBase* obj, const char* msg, const char* str, int pos -//------------------ class mjCAlternative implementation ------------------------------------------- - -// constructor -mjCAlternative::mjCAlternative() { - axisangle[0] = xyaxes[0] = zaxis[0] = euler[0] = mjNAN; -} - +//------------------ alternative orientation implementation ---------------------------------------- // compute frame orientation given alternative specifications // used for geom, site, body and camera frames -const char* mjCAlternative::Set(double* quat, bool degree, const char* sequence) { +const char* ResolveOrientation(double* quat, bool degree, const char* sequence, + const mjsOrientation& orient) { + mjtNum axisangle[4]; + mjtNum xyaxes[6]; + mjtNum zaxis[3]; + mjtNum euler[3]; + + mjuu_copyvec(axisangle, orient.axisangle, 4); + mjuu_copyvec(xyaxes, orient.xyaxes, 6); + mjuu_copyvec(zaxis, orient.zaxis, 3); + mjuu_copyvec(euler, orient.euler, 3); + // set quat using axisangle if (mjuu_defined(axisangle[0])) { // convert to radians if necessary, normalize axis @@ -754,14 +759,6 @@ void mjCBody::CopyFromSpec() { *static_cast(this) = spec; userdata_ = spec_userdata_; userdata = (mjDoubleVec)&userdata_; - mju_copy4(alt_.axisangle, alt.axisangle); - mju_copy(alt_.xyaxes, alt.xyaxes, 6); - mju_copy3(alt_.zaxis, alt.zaxis); - mju_copy3(alt_.euler, alt.euler); - mju_copy4(ialt_.axisangle, ialt.axisangle); - mju_copy(ialt_.xyaxes, ialt.xyaxes, 6); - mju_copy3(ialt_.zaxis, ialt.zaxis); - mju_copy3(ialt_.euler, ialt.euler); plugin.active = spec.plugin.active; plugin.instance = spec.plugin.instance; plugin.name = spec.plugin.name; @@ -1195,7 +1192,7 @@ void mjCBody::Compile(void) { } // check and process orientation alternatives for body - const char* err = alt_.Set(quat, model->degree, model->euler); + const char* err = ResolveOrientation(quat, model->degree, model->euler, alt); if (err) { throw mjCError(this, "error '%s' in frame alternative", err); } @@ -1432,10 +1429,6 @@ void mjCFrame::CopyFromSpec() { *static_cast(this) = spec; mju_copy3(pos, spec.pos); mju_copy4(quat, spec.quat); - mju_copy4(alt_.axisangle, alt.axisangle); - mju_copy(alt_.xyaxes, alt.xyaxes, 6); - mju_copy3(alt_.zaxis, alt.zaxis); - mju_copy3(alt_.euler, alt.euler); } @@ -1446,7 +1439,7 @@ void mjCFrame::Compile() { } CopyFromSpec(); - const char* err = alt_.Set(quat, model->spec.degree, model->spec.euler); + const char* err = ResolveOrientation(quat, model->spec.degree, model->spec.euler, alt); if (err) { throw mjCError(this, "orientation specification error '%s' in site %d", err, id); } @@ -1746,10 +1739,6 @@ void mjCGeom::CopyFromSpec() { hfieldname = (mjString)&hfieldname_; meshname = (mjString)&meshname_; material = (mjString)&material_; - mju_copy4(alt_.axisangle, alt.axisangle); - mju_copy(alt_.xyaxes, alt.xyaxes, 6); - mju_copy3(alt_.zaxis, alt.zaxis); - mju_copy3(alt_.euler, alt.euler); plugin.active = spec.plugin.active; plugin.instance = spec.plugin.instance; plugin.name = spec.plugin.name; @@ -2181,7 +2170,7 @@ void mjCGeom::Compile(void) { // not 'fromto': try alternative else { - const char* err = alt_.Set(quat, model->degree, model->euler); + const char* err = ResolveOrientation(quat, model->degree, model->euler, alt); if (err) { throw mjCError(this, "orientation specification error '%s' in geom %d", err, id); } @@ -2355,10 +2344,6 @@ void mjCSite::CopyFromSpec() { material_ = spec_material_; userdata = (mjDoubleVec)&userdata_; material = (mjString)&material_; - mju_copy4(alt_.axisangle, alt.axisangle); - mju_copy(alt_.xyaxes, alt.xyaxes, 6); - mju_copy3(alt_.zaxis, alt.zaxis); - mju_copy3(alt_.euler, alt.euler); } @@ -2430,7 +2415,7 @@ void mjCSite::Compile(void) { // alternative orientation else { - const char* err = alt_.Set(quat, model->degree, model->euler); + const char* err = ResolveOrientation(quat, model->degree, model->euler, alt); if (err) { throw mjCError(this, "orientation specification error '%s' in site %d", err, id); } @@ -2514,10 +2499,6 @@ void mjCCamera::CopyFromSpec() { targetbody_ = spec_targetbody_; userdata = (mjDoubleVec)&userdata_; targetbody = (mjString)&targetbody_; - mju_copy4(alt_.axisangle, alt.axisangle); - mju_copy(alt_.xyaxes, alt.xyaxes, 6); - mju_copy3(alt_.zaxis, alt.zaxis); - mju_copy3(alt_.euler, alt.euler); } @@ -2534,7 +2515,7 @@ void mjCCamera::Compile(void) { userdata_.resize(model->nuser_cam); // process orientation specifications - const char* err = alt_.Set(quat, model->degree, model->euler); + const char* err = ResolveOrientation(quat, model->degree, model->euler, alt); if (err) { throw mjCError(this, "orientation specification error '%s' in camera %d", err, id); } diff --git a/src/user/user_objects.h b/src/user/user_objects.h index 0cf4fbde..fa29ea16 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -30,7 +30,6 @@ // forward declarations of all mjC/X classes class mjCError; -class mjCAlternative; class mjCBase; class mjCBody; class mjCFrame; @@ -82,13 +81,10 @@ class [[nodiscard]] mjCError { // alternative specifications of frame orientation -class mjCAlternative : public mjsOrientation { - public: - mjCAlternative(); // constuctor - const char* Set(double* quat, // set frame quat - bool degree, // angle format: degree/radian - const char* sequence); // euler sequence format: "xyz" -}; +const char* ResolveOrientation(double* quat, // set frame quat + bool degree, // angle format: degree/radian + const char* sequence, // euler sequence format: "xyz" + const mjsOrientation& orient); @@ -223,10 +219,6 @@ class mjCBase : public mjCBase_ { // Describes a rigid body class mjCBody_ : public mjCBase { - public: - mjCAlternative alt_; - mjCAlternative ialt_; - protected: // variables computed by 'Compile' and 'AddXXX' int parentid; // parent index in global array @@ -340,7 +332,6 @@ class mjCBody : public mjCBody_, private mjsBody { class mjCFrame_ : public mjCBase { protected: bool compiled; // frame already compiled - mjCAlternative alt_; }; class mjCFrame : public mjCFrame_, private mjsFrame { @@ -433,7 +424,6 @@ class mjCGeom_ : public mjCBase { bool inferinertia; // true if inertia should be computed from geom protected: - mjCAlternative alt_; bool visual_; // true: geom does not collide and is unreferenced int matid; // id of geom's material mjCMesh* mesh; // geom's mesh @@ -513,8 +503,6 @@ class mjCGeom : public mjCGeom_, private mjsGeom { class mjCSite_ : public mjCBase { protected: - mjCAlternative alt_; - // variable-size data std::string material_; std::vector userdata_; @@ -565,7 +553,6 @@ class mjCCamera_ : public mjCBase { protected: mjCBody* body; // camera's body int targetbodyid; // id of target body; -1: none - mjCAlternative alt_; std::string targetbody_; std::string spec_targetbody_; std::vector userdata_; diff --git a/src/xml/xml_urdf.cc b/src/xml/xml_urdf.cc index 28e76beb..0d7f6381 100644 --- a/src/xml/xml_urdf.cc +++ b/src/xml/xml_urdf.cc @@ -20,7 +20,6 @@ #include #include "user/user_api.h" -#include "user/user_objects.h" #include "user/user_util.h" #include "xml/xml_native_reader.h" #include "xml/xml_urdf.h" @@ -633,9 +632,10 @@ void mjXURDF::Origin(XMLElement* origin_elem, double* pos, double* quat) { ReadAttr(temp, "xyz", 3, pos, text); // orientation - mjCAlternative alt; + mjsOrientation alt; + mjs_defaultOrientation(alt); if (ReadAttr(temp, "rpy", 3, alt.euler, text)) { - alt.Set(quat, 0, "XYZ"); + mjs_resolveOrientation(quat, 0, "XYZ", &alt); } } } From 709719911eb4323879f262829659c6d38493f4bc Mon Sep 17 00:00:00 2001 From: Kyle Bayes Date: Tue, 26 Mar 2024 03:18:21 -0700 Subject: [PATCH 37/51] Make SameVector return early. PiperOrigin-RevId: 619128273 Change-Id: Ic47613b8322b9ff5a6a1f557cc9626a20aaee794 --- src/xml/xml_util.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/xml/xml_util.cc b/src/xml/xml_util.cc index fcda1791..d5250cbc 100644 --- a/src/xml/xml_util.cc +++ b/src/xml/xml_util.cc @@ -523,14 +523,13 @@ bool mjXUtil::SameVector(const T* vec1, const T* vec2, int n) { return false; } - bool same = true; - for (int i=0; i std::numeric_limits::epsilon()) { - same = false; + return false; } } - return same; + return true; } template bool mjXUtil::SameVector(const double* vec1, const double* vec2, int n); From fa8893b443df408a327f298aef84778e155a94d9 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Tue, 26 Mar 2024 06:49:58 -0700 Subject: [PATCH 38/51] Improve hash function for names. PiperOrigin-RevId: 619173787 Change-Id: I7889ea71ebe7bdbe682042842c521d6631521a35 --- src/engine/engine_support.c | 6 +++--- src/engine/engine_support.h | 2 +- src/user/user_model.cc | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/engine/engine_support.c b/src/engine/engine_support.c index c3601931..5deb1e72 100644 --- a/src/engine/engine_support.c +++ b/src/engine/engine_support.c @@ -1050,11 +1050,11 @@ static int _getnumadr(const mjModel* m, mjtObj type, int** padr, int* mapadr) { } // get string hash, see http://www.cse.yorku.ca/~oz/hash.html -uint64_t mj_hashdjb2(const char* s, uint64_t n) { +uint64_t mj_hashString(const char* s, uint64_t n) { uint64_t h = 5381; int c; while ((c = *s++)) { - h = ((h << 5) + h) + c; + h = ((h << 5) + h) ^ c; } return h % n; } @@ -1070,7 +1070,7 @@ int mj_name2id(const mjModel* m, int type, const char* name) { // search if (num) { // look up at hash address - uint64_t hash = mj_hashdjb2(name, num); + uint64_t hash = mj_hashString(name, num); uint64_t i = hash; do { diff --git a/src/engine/engine_support.h b/src/engine/engine_support.h index 122c59ba..a5d3c7ae 100644 --- a/src/engine/engine_support.h +++ b/src/engine/engine_support.h @@ -114,7 +114,7 @@ MJAPI void mj_angmomMat(const mjModel* m, mjData* d, mjtNum* mat, int body); //-------------------------- name functions -------------------------------------------------------- // get string hash, see http://www.cse.yorku.ca/~oz/hash.html -uint64_t mj_hashdjb2(const char* s, uint64_t n); +uint64_t mj_hashString(const char* s, uint64_t n); // get id of object with the specified mjtObj type and name, returns -1 if id not found MJAPI int mj_name2id(const mjModel* m, int type, const char* name); diff --git a/src/user/user_model.cc b/src/user/user_model.cc index d8a72c50..c160a8a0 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -1492,7 +1492,7 @@ static int namelist(vector& list, int adr, int* name_adr, char* names, int* continue; } - uint64_t j = mj_hashdjb2(list[i]->name.c_str(), map_size); + uint64_t j = mj_hashString(list[i]->name.c_str(), map_size); // find first empty slot using linear probing for (; map[j]!=-1; j=(j+1) % map_size) {} From 4d2aa46e561abcfffd5317b6c5aa4c9b6d9199c8 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Tue, 26 Mar 2024 07:18:57 -0700 Subject: [PATCH 39/51] Rename `mjmDefault` -> `mjsDefault` PiperOrigin-RevId: 619180662 Change-Id: Id7cedf82fbb022f08accc7c9a547495ed8eecba0 --- src/user/user_api.cc | 34 ++++++++++++++++---------------- src/user/user_api.h | 38 ++++++++++++++++++------------------ src/user/user_objects.h | 2 +- src/xml/xml_native_reader.cc | 28 +++++++++++++------------- src/xml/xml_native_reader.h | 4 ++-- 5 files changed, 53 insertions(+), 53 deletions(-) diff --git a/src/user/user_api.cc b/src/user/user_api.cc index 3469f367..a0ca98e6 100644 --- a/src/user/user_api.cc +++ b/src/user/user_api.cc @@ -116,7 +116,7 @@ void mjs_deleteSpec(mjSpec* s) { // add child body to body, return child spec -mjsBody* mjs_addBody(mjsBody* bodyspec, mjmDefault* defspec) { +mjsBody* mjs_addBody(mjsBody* bodyspec, mjsDefault* defspec) { mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCBody* body = reinterpret_cast(bodyspec->element)->AddBody(def); return &body->spec; @@ -125,7 +125,7 @@ mjsBody* mjs_addBody(mjsBody* bodyspec, mjmDefault* defspec) { // add site to body, return site spec -mjsSite* mjs_addSite(mjsBody* bodyspec, mjmDefault* defspec) { +mjsSite* mjs_addSite(mjsBody* bodyspec, mjsDefault* defspec) { mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCBody* body = reinterpret_cast(bodyspec->element); mjCSite* site = body->AddSite(def); @@ -135,7 +135,7 @@ mjsSite* mjs_addSite(mjsBody* bodyspec, mjmDefault* defspec) { // add joint to body -mjsJoint* mjs_addJoint(mjsBody* bodyspec, mjmDefault* defspec) { +mjsJoint* mjs_addJoint(mjsBody* bodyspec, mjsDefault* defspec) { mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCBody* body = reinterpret_cast(bodyspec->element); mjCJoint* joint = body->AddJoint(def); @@ -154,7 +154,7 @@ mjsJoint* mjs_addFreeJoint(mjsBody* bodyspec) { // add geom to body -mjsGeom* mjs_addGeom(mjsBody* bodyspec, mjmDefault* defspec) { +mjsGeom* mjs_addGeom(mjsBody* bodyspec, mjsDefault* defspec) { mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCBody* body = reinterpret_cast(bodyspec->element); mjCGeom* geom = body->AddGeom(def); @@ -164,7 +164,7 @@ mjsGeom* mjs_addGeom(mjsBody* bodyspec, mjmDefault* defspec) { // add camera to body -mjsCamera* mjs_addCamera(mjsBody* bodyspec, mjmDefault* defspec) { +mjsCamera* mjs_addCamera(mjsBody* bodyspec, mjsDefault* defspec) { mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCBody* body = reinterpret_cast(bodyspec->element); mjCCamera* camera = body->AddCamera(def); @@ -174,7 +174,7 @@ mjsCamera* mjs_addCamera(mjsBody* bodyspec, mjmDefault* defspec) { // add light to body -mjsLight* mjs_addLight(mjsBody* bodyspec, mjmDefault* defspec) { +mjsLight* mjs_addLight(mjsBody* bodyspec, mjsDefault* defspec) { mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCBody* body = reinterpret_cast(bodyspec->element); mjCLight* light = body->AddLight(def); @@ -207,7 +207,7 @@ mjsFrame* mjs_addFrame(mjsBody* bodyspec, mjsFrame* parentframe) { // add mesh to model -mjsMesh* mjs_addMesh(mjSpec* s, mjmDefault* defspec) { +mjsMesh* mjs_addMesh(mjSpec* s, mjsDefault* defspec) { mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCModel* modelC = reinterpret_cast(s->element); mjCMesh* mesh = modelC->AddMesh(def); @@ -244,7 +244,7 @@ mjsTexture* mjs_addTexture(mjSpec* s) { // add material to model -mjsMaterial* mjs_addMaterial(mjSpec* s, mjmDefault* defspec) { +mjsMaterial* mjs_addMaterial(mjSpec* s, mjsDefault* defspec) { mjCModel* modelC = reinterpret_cast(s->element); mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCMaterial* material = modelC->AddMaterial(def); @@ -254,7 +254,7 @@ mjsMaterial* mjs_addMaterial(mjSpec* s, mjmDefault* defspec) { // add pair to model -mjsPair* mjs_addPair(mjSpec* s, mjmDefault* defspec) { +mjsPair* mjs_addPair(mjSpec* s, mjsDefault* defspec) { mjCModel* modelC = reinterpret_cast(s->element); mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCPair* pair = modelC->AddPair(def); @@ -273,7 +273,7 @@ mjsExclude* mjs_addExclude(mjSpec* s) { // add equality to model -mjsEquality* mjs_addEquality(mjSpec* s, mjmDefault* defspec) { +mjsEquality* mjs_addEquality(mjSpec* s, mjsDefault* defspec) { mjCModel* modelC = reinterpret_cast(s->element); mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCEquality* equality = modelC->AddEquality(def); @@ -283,7 +283,7 @@ mjsEquality* mjs_addEquality(mjSpec* s, mjmDefault* defspec) { // add tendon to model -mjsTendon* mjs_addTendon(mjSpec* s, mjmDefault* defspec) { +mjsTendon* mjs_addTendon(mjSpec* s, mjsDefault* defspec) { mjCModel* modelC = reinterpret_cast(s->element); mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCTendon* tendon = modelC->AddTendon(def); @@ -329,7 +329,7 @@ mjsWrap* mjs_wrapPulley(mjsTendon* tendonspec, double divisor) { // add actuator to model -mjsActuator* mjs_addActuator(mjSpec* s, mjmDefault* defspec) { +mjsActuator* mjs_addActuator(mjSpec* s, mjsDefault* defspec) { mjCModel* modelC = reinterpret_cast(s->element); mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; mjCActuator* actuator = modelC->AddActuator(def); @@ -394,7 +394,7 @@ mjsPlugin* mjs_addPlugin(mjSpec* s) { // add default to model -mjmDefault* mjs_addDefault(mjSpec* s, const char* classname, int parentid, int* id) { +mjsDefault* mjs_addDefault(mjSpec* s, const char* classname, int parentid, int* id) { mjCModel* modelC = reinterpret_cast(s->element); *id = (int)modelC->defaults.size(); mjCDef* def = modelC->AddDef(classname, parentid); @@ -415,14 +415,14 @@ mjSpec* mjs_getSpec(mjsBody* body) { // get default -mjmDefault* mjs_getDefault(mjElement element) { +mjsDefault* mjs_getDefault(mjElement element) { return &(reinterpret_cast(element)->def->spec); } // Find default with given name in model. -mjmDefault* mjs_findDefault(mjSpec* s, const char* classname) { +mjsDefault* mjs_findDefault(mjSpec* s, const char* classname) { mjCModel* modelC = reinterpret_cast(s->element); mjCDef* cdef = modelC->FindDef(classname); if (!cdef) { @@ -434,7 +434,7 @@ mjmDefault* mjs_findDefault(mjSpec* s, const char* classname) { // get default[0] from model -mjmDefault* mjs_getSpecDefault(mjSpec* s) { +mjsDefault* mjs_getSpecDefault(mjSpec* s) { mjCModel* modelC = reinterpret_cast(s->element); mjCDef* def = modelC->defaults[0]; if (!def) { @@ -514,7 +514,7 @@ int mjs_getId(mjElement element) { // set default -void mjs_setDefault(mjElement element, mjmDefault* defspec) { +void mjs_setDefault(mjElement element, mjsDefault* defspec) { mjCBase* baseC = reinterpret_cast(element); baseC->def = reinterpret_cast(defspec->element); } diff --git a/src/user/user_api.h b/src/user/user_api.h index db24d853..a9ac8bde 100644 --- a/src/user/user_api.h +++ b/src/user/user_api.h @@ -708,7 +708,7 @@ typedef struct _mjsKey { // keyframe specification } mjsKey; -typedef struct _mjmDefault { // default specification +typedef struct _mjsDefault { // default specification mjString name; // name mjElement element; // internal, do not modify mjsJoint* joint; // joint defaults @@ -723,7 +723,7 @@ typedef struct _mjmDefault { // default specification mjsEquality* equality; // equality defaults mjsTendon* tendon; // tendon defaults mjsActuator* actuator; // actuator defaults -} mjmDefault; +} mjsDefault; //---------------------------------- API functions ------------------------------------------------- @@ -754,25 +754,25 @@ MJAPI int mjs_isWarning(mjSpec* s); MJAPI void mjs_deleteSpec(mjSpec* s); // Add child body to body, return child spec. -MJAPI mjsBody* mjs_addBody(mjsBody* body, mjmDefault* def); +MJAPI mjsBody* mjs_addBody(mjsBody* body, mjsDefault* def); // Add site to body, return site spec. -MJAPI mjsSite* mjs_addSite(mjsBody* body, mjmDefault* def); +MJAPI mjsSite* mjs_addSite(mjsBody* body, mjsDefault* def); // Add joint to body. -MJAPI mjsJoint* mjs_addJoint(mjsBody* body, mjmDefault* def); +MJAPI mjsJoint* mjs_addJoint(mjsBody* body, mjsDefault* def); // Add freejoint to body. MJAPI mjsJoint* mjs_addFreeJoint(mjsBody* body); // Add geom to body. -MJAPI mjsGeom* mjs_addGeom(mjsBody* body, mjmDefault* def); +MJAPI mjsGeom* mjs_addGeom(mjsBody* body, mjsDefault* def); // Add camera to body. -MJAPI mjsCamera* mjs_addCamera(mjsBody* body, mjmDefault* def); +MJAPI mjsCamera* mjs_addCamera(mjsBody* body, mjsDefault* def); // Add light to body. -MJAPI mjsLight* mjs_addLight(mjsBody* body, mjmDefault* def); +MJAPI mjsLight* mjs_addLight(mjsBody* body, mjsDefault* def); // Add frame to body. MJAPI mjsFrame* mjs_addFrame(mjsBody* body, mjsFrame* parentframe); @@ -781,7 +781,7 @@ MJAPI mjsFrame* mjs_addFrame(mjsBody* body, mjsFrame* parentframe); MJAPI mjsFlex* mjs_addFlex(mjSpec* s); // Add mesh to model. -MJAPI mjsMesh* mjs_addMesh(mjSpec* s, mjmDefault* def); +MJAPI mjsMesh* mjs_addMesh(mjSpec* s, mjsDefault* def); // Add height field to model. MJAPI mjsHField* mjs_addHField(mjSpec* s); @@ -793,19 +793,19 @@ MJAPI mjsSkin* mjs_addSkin(mjSpec* s); MJAPI mjsTexture* mjs_addTexture(mjSpec* s); // Add material to model. -MJAPI mjsMaterial* mjs_addMaterial(mjSpec* s, mjmDefault* def); +MJAPI mjsMaterial* mjs_addMaterial(mjSpec* s, mjsDefault* def); // Add pair to model. -MJAPI mjsPair* mjs_addPair(mjSpec* s, mjmDefault* def); +MJAPI mjsPair* mjs_addPair(mjSpec* s, mjsDefault* def); // Add excluded body pair to model. MJAPI mjsExclude* mjs_addExclude(mjSpec* s); // Add equality to model. -MJAPI mjsEquality* mjs_addEquality(mjSpec* s, mjmDefault* def); +MJAPI mjsEquality* mjs_addEquality(mjSpec* s, mjsDefault* def); // Add tendon to model. -MJAPI mjsTendon* mjs_addTendon(mjSpec* s, mjmDefault* def); +MJAPI mjsTendon* mjs_addTendon(mjSpec* s, mjsDefault* def); // Wrap site using tendon. MJAPI mjsWrap* mjs_wrapSite(mjsTendon* tendon, const char* name); @@ -820,7 +820,7 @@ MJAPI mjsWrap* mjs_wrapJoint(mjsTendon* tendon, const char* name, double coef); MJAPI mjsWrap* mjs_wrapPulley(mjsTendon* tendon, double divisor); // Add actuator to model. -MJAPI mjsActuator* mjs_addActuator(mjSpec* s, mjmDefault* def); +MJAPI mjsActuator* mjs_addActuator(mjSpec* s, mjsDefault* def); // Add sensor to model. MJAPI mjsSensor* mjs_addSensor(mjSpec* s); @@ -841,19 +841,19 @@ MJAPI mjsKey* mjs_addKey(mjSpec* s); MJAPI mjsPlugin* mjs_addPlugin(mjSpec* s); // Add default to model. -MJAPI mjmDefault* mjs_addDefault(mjSpec* s, const char* classname, int parentid, int* id); +MJAPI mjsDefault* mjs_addDefault(mjSpec* s, const char* classname, int parentid, int* id); // Get model spec from body. MJAPI mjSpec* mjs_getSpec(mjsBody* body); // Get default corresponding to an mjElement. -MJAPI mjmDefault* mjs_getDefault(mjElement element); +MJAPI mjsDefault* mjs_getDefault(mjElement element); // Find default in model by class name. -MJAPI mjmDefault* mjs_findDefault(mjSpec* s, const char* classname); +MJAPI mjsDefault* mjs_findDefault(mjSpec* s, const char* classname); // Get global default from model. -MJAPI mjmDefault* mjs_getSpecDefault(mjSpec* s); +MJAPI mjsDefault* mjs_getSpecDefault(mjSpec* s); // Find body in model by name. MJAPI mjsBody* mjs_findBody(mjSpec* s, const char* name); @@ -910,7 +910,7 @@ MJAPI void mjs_setPluginAttributes(mjsPlugin* plugin, void* attributes); MJAPI void mjs_setActivePlugins(mjSpec* s, void* activeplugins); // Set default. -MJAPI void mjs_setDefault(mjElement element, mjmDefault* def); +MJAPI void mjs_setDefault(mjElement element, mjsDefault* def); // Set frame. MJAPI void mjs_setFrame(mjElement dest, mjsFrame* frame); diff --git a/src/user/user_objects.h b/src/user/user_objects.h index fa29ea16..1e24ab34 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -1622,7 +1622,7 @@ class mjCDef { int parentid; // id of parent class std::vector childid; // ids of child classes - mjmDefault spec; + mjsDefault spec; // default objects (TODO: they should become private) mjCJoint joint; diff --git a/src/xml/xml_native_reader.cc b/src/xml/xml_native_reader.cc index 667364d3..48f5547f 100644 --- a/src/xml/xml_native_reader.cc +++ b/src/xml/xml_native_reader.cc @@ -2241,7 +2241,7 @@ void mjXReader::OneActuator(XMLElement* elem, mjsActuator* pact) { // make composite -void mjXReader::OneComposite(XMLElement* elem, mjsBody* pbody, mjmDefault* def) { +void mjXReader::OneComposite(XMLElement* elem, mjsBody* pbody, mjsDefault* def) { string text; int n; @@ -2371,7 +2371,7 @@ void mjXReader::OneComposite(XMLElement* elem, mjsBody* pbody, mjmDefault* def) comp.add[kind] = true; // get element - mjmDefault* dspec = &comp.defjoint[(mjtCompKind)kind].back().spec; + mjsDefault* dspec = &comp.defjoint[(mjtCompKind)kind].back().spec; mjsJoint& djoint = *dspec->joint; mjsEquality& dequality = *dspec->equality; @@ -2623,7 +2623,7 @@ void mjXReader::OnePlugin(XMLElement* elem, mjsPlugin* plugin) { void mjXReader::Default(XMLElement* section, int parentid) { XMLElement* elem; string text, name; - mjmDefault* def; + mjsDefault* def; int thisid; // create new default, except at top level (already added in mjCModel ctor) @@ -3044,7 +3044,7 @@ void mjXReader::Asset(XMLElement* section) { name = elem->Value(); // get class if specified, otherwise use default0 - mjmDefault* def = GetClass(elem); + mjsDefault* def = GetClass(elem); if (!def) { def = mjs_getSpecDefault(model); } @@ -3226,7 +3226,7 @@ void mjXReader::Body(XMLElement* section, mjsBody* pbody, mjsFrame* frame) { name = elem->Value(); // get class if specified, otherwise use body - mjmDefault* def = GetClass(elem); + mjsDefault* def = GetClass(elem); if (!def) { def = mjs_getDefault(frame ? frame->element : pbody->element); } @@ -3336,7 +3336,7 @@ void mjXReader::Body(XMLElement* section, mjsBody* pbody, mjsFrame* frame) { // frame sub-element else if (name=="frame") { // read childdef - mjmDefault* childdef = 0; + mjsDefault* childdef = 0; if (ReadAttrTxt(elem, "childclass", text)) { childdef = mjs_findDefault(model, text.c_str()); mjs_findDefault(model, text.c_str()); @@ -3368,7 +3368,7 @@ void mjXReader::Body(XMLElement* section, mjsBody* pbody, mjsFrame* frame) { // body sub-element else if (name=="body") { // read childdef - mjmDefault* childdef = 0; + mjsDefault* childdef = 0; if (ReadAttrTxt(elem, "childclass", text)) { childdef = mjs_findDefault(model, text.c_str()); mjs_findDefault(model, text.c_str()); @@ -3436,7 +3436,7 @@ void mjXReader::Contact(XMLElement* section) { name = elem->Value(); // get class if specified, otherwise use default0 - mjmDefault* def = GetClass(elem); + mjsDefault* def = GetClass(elem); if (!def) { def = mjs_getSpecDefault(model); } @@ -3481,7 +3481,7 @@ void mjXReader::Equality(XMLElement* section) { elem = FirstChildElement(section); while (elem) { // get class if specified, otherwise use default0 - mjmDefault* def = GetClass(elem); + mjsDefault* def = GetClass(elem); if (!def) { def = mjs_getSpecDefault(model); } @@ -3509,7 +3509,7 @@ void mjXReader::Deformable(XMLElement* section) { name = elem->Value(); // get class if specified, otherwise use default0 - mjmDefault* def = GetClass(elem); + mjsDefault* def = GetClass(elem); if (!def) { def = mjs_getSpecDefault(model); } @@ -3545,7 +3545,7 @@ void mjXReader::Tendon(XMLElement* section) { elem = FirstChildElement(section); while (elem) { // get class if specified, otherwise use default0 - mjmDefault* def = GetClass(elem); + mjsDefault* def = GetClass(elem); if (!def) { def = mjs_getSpecDefault(model); } @@ -3611,7 +3611,7 @@ void mjXReader::Actuator(XMLElement* section) { elem = FirstChildElement(section); while (elem) { // get class if specified, otherwise use default0 - mjmDefault* def = GetClass(elem); + mjsDefault* def = GetClass(elem); if (!def) { def = mjs_getSpecDefault(model); } @@ -4001,9 +4001,9 @@ void mjXReader::Keyframe(XMLElement* section) { // get defaults class -mjmDefault* mjXReader::GetClass(XMLElement* section) { +mjsDefault* mjXReader::GetClass(XMLElement* section) { string text; - mjmDefault* def = nullptr; + mjsDefault* def = nullptr; if (ReadAttrTxt(section, "class", text)) { def = mjs_findDefault(model, text.c_str()); diff --git a/src/xml/xml_native_reader.h b/src/xml/xml_native_reader.h index 50d28a9a..c0b36748 100644 --- a/src/xml/xml_native_reader.h +++ b/src/xml/xml_native_reader.h @@ -78,12 +78,12 @@ class mjXReader : public mjXBase { void OneEquality(tinyxml2::XMLElement* elem, mjsEquality* pequality); void OneTendon(tinyxml2::XMLElement* elem, mjsTendon* ptendon); void OneActuator(tinyxml2::XMLElement* elem, mjsActuator* pactuator); - void OneComposite(tinyxml2::XMLElement* elem, mjsBody* pbody, mjmDefault* def); + void OneComposite(tinyxml2::XMLElement* elem, mjsBody* pbody, mjsDefault* def); void OneFlexcomp(tinyxml2::XMLElement* elem, mjsBody* pbody); void OnePlugin(tinyxml2::XMLElement* elem, mjsPlugin* plugin); mjXSchema schema; // schema used for validation - mjmDefault* GetClass(tinyxml2::XMLElement* section); // get default class name + mjsDefault* GetClass(tinyxml2::XMLElement* section); // get default class name bool readingdefaults; // true while reading defaults From 4f0293c6cbe242b405634efd6b45ce4f837d0c3a Mon Sep 17 00:00:00 2001 From: Google DeepMind Date: Tue, 26 Mar 2024 10:11:07 -0700 Subject: [PATCH 40/51] Added support for msh2.2 Now we can load flex with format 2.2 binary and ASCII. There are two different parsing strategies. One for gmsh app and the other is for ftetwild. Used the shark model from Scanned Objects by Google Research: https://app.gazebosim.org/GoogleResearch/fuel/models/Weisshai_Great_White_Shark PiperOrigin-RevId: 619229499 Change-Id: I6eb876afcbc8a00631914b093c45bde10c0caaf6 --- doc/XMLreference.rst | 12 +- doc/changelog.rst | 14 +- src/user/user_flexcomp.cc | 676 ++- src/user/user_flexcomp.h | 5 + test/sample/testspeed_test.sh | 10 +- ...lformed_shark_22_ascii_missing_element.xml | 25 + .../malformed_shark_22_ascii_missing_node.xml | 27 + ...ed_shark_22_ascii_missing_num_elements.xml | 27 + ...ormed_shark_22_ascii_missing_num_nodes.xml | 27 + ...lformed_shark_41_ascii_missing_element.xml | 27 + ..._shark_41_ascii_missing_element_header.xml | 27 + ...med_shark_41_ascii_missing_node_header.xml | 27 + ...rmed_shark_41_ascii_missing_node_index.xml | 27 + .../user/testdata/shark_22_ascii_fTetWild.msh | 3979 +++++++++++++++++ .../user/testdata/shark_22_ascii_fTetWild.xml | 25 + test/user/testdata/shark_22_ascii_gmshApp.msh | 2315 ++++++++++ test/user/testdata/shark_22_ascii_gmshApp.xml | 25 + .../shark_22_ascii_missing_element.msh | 3978 ++++++++++++++++ .../testdata/shark_22_ascii_missing_node.msh | 3978 ++++++++++++++++ .../shark_22_ascii_missing_num_elements.msh | 3978 ++++++++++++++++ .../shark_22_ascii_missing_num_nodes.msh | 3978 ++++++++++++++++ .../testdata/shark_22_binary_fTetWild.msh | Bin 0 -> 70508 bytes .../testdata/shark_22_binary_fTetWild.xml | 25 + .../user/testdata/shark_22_binary_gmshApp.msh | Bin 0 -> 83523 bytes .../user/testdata/shark_22_binary_gmshApp.xml | 25 + test/user/testdata/shark_41_ascii_gmshApp.msh | 2973 ++++++++++++ test/user/testdata/shark_41_ascii_gmshApp.xml | 25 + .../shark_41_ascii_missing_element.msh | 2972 ++++++++++++ .../shark_41_ascii_missing_element_header.msh | 2972 ++++++++++++ .../shark_41_ascii_missing_node_header.msh | 2972 ++++++++++++ .../shark_41_ascii_missing_node_index.msh | 2973 ++++++++++++ .../user/testdata/shark_41_binary_gmshApp.msh | Bin 0 -> 87334 bytes .../user/testdata/shark_41_binary_gmshApp.xml | 25 + test/user/user_flex_test.cc | 172 + test/xml/xml_native_writer_test.cc | 1 + 35 files changed, 38103 insertions(+), 219 deletions(-) create mode 100644 test/user/testdata/malformed_shark_22_ascii_missing_element.xml create mode 100644 test/user/testdata/malformed_shark_22_ascii_missing_node.xml create mode 100644 test/user/testdata/malformed_shark_22_ascii_missing_num_elements.xml create mode 100644 test/user/testdata/malformed_shark_22_ascii_missing_num_nodes.xml create mode 100644 test/user/testdata/malformed_shark_41_ascii_missing_element.xml create mode 100644 test/user/testdata/malformed_shark_41_ascii_missing_element_header.xml create mode 100644 test/user/testdata/malformed_shark_41_ascii_missing_node_header.xml create mode 100644 test/user/testdata/malformed_shark_41_ascii_missing_node_index.xml create mode 100644 test/user/testdata/shark_22_ascii_fTetWild.msh create mode 100644 test/user/testdata/shark_22_ascii_fTetWild.xml create mode 100644 test/user/testdata/shark_22_ascii_gmshApp.msh create mode 100644 test/user/testdata/shark_22_ascii_gmshApp.xml create mode 100644 test/user/testdata/shark_22_ascii_missing_element.msh create mode 100644 test/user/testdata/shark_22_ascii_missing_node.msh create mode 100644 test/user/testdata/shark_22_ascii_missing_num_elements.msh create mode 100644 test/user/testdata/shark_22_ascii_missing_num_nodes.msh create mode 100644 test/user/testdata/shark_22_binary_fTetWild.msh create mode 100644 test/user/testdata/shark_22_binary_fTetWild.xml create mode 100644 test/user/testdata/shark_22_binary_gmshApp.msh create mode 100644 test/user/testdata/shark_22_binary_gmshApp.xml create mode 100644 test/user/testdata/shark_41_ascii_gmshApp.msh create mode 100644 test/user/testdata/shark_41_ascii_gmshApp.xml create mode 100644 test/user/testdata/shark_41_ascii_missing_element.msh create mode 100644 test/user/testdata/shark_41_ascii_missing_element_header.msh create mode 100644 test/user/testdata/shark_41_ascii_missing_node_header.msh create mode 100644 test/user/testdata/shark_41_ascii_missing_node_index.msh create mode 100644 test/user/testdata/shark_41_binary_gmshApp.msh create mode 100644 test/user/testdata/shark_41_binary_gmshApp.xml diff --git a/doc/XMLreference.rst b/doc/XMLreference.rst index 11138022..e9bbde58 100644 --- a/doc/XMLreference.rst +++ b/doc/XMLreference.rst @@ -3808,8 +3808,12 @@ saving the XML: in MuJoCo can be used as a rigid geom attached to a single body. In contrast, the flex generated here corresponds to a soft mesh with the same initial shape, where each vertex is a separate moving body (unless pinned). - **gmsh** is similar to mesh, but it loads a `GMSH file `__ - in format 4.1 (ascii or binary). The file extension can be anything; the parser recognizes the format by examining + .. _gmsh-file-docs: + + **gmsh** is similar to mesh, but it loads a GMSH file in + `format 4.1 `__ + and `format 2.2 `__ + (ascii or binary). The file extension can be anything; the parser recognizes the format by examining the file header. This is a very rich file format, allowing all kinds of elements with different dimensionality and topology. MuJoCo only supports GMSH element types 1, 2, 4 which happen to correspond to our 1D, 2D and 3D flexes and assumes that the nodes are specified in a single block. Only the Nodes and Elements sections of the GMHS file are @@ -3817,7 +3821,7 @@ saving the XML: GMSH file contains meshes that are not supported by MuJoCo. :at:`dim` is automatically set to the dimensionality specified in the GMSH file. Presently this is the only mechanism to load a large tetrahedral mesh in MuJoCo and generate a corresponding soft entity. If such a mesh is available in a different file format, use the freely - available `GMSH software `__ to convert it to GMSH 4.1. + available `GMSH software `__ to convert it to GMSH in one of the supported versions. **direct** allows the user to specify the point and element data of the flexcomp directly in the XML. Note that flexcomp will still generate moving bodies automatically, as well as automate other settings; so it still provides @@ -3873,7 +3877,7 @@ saving the XML: :at:`file`: :at-val:`string, optional` The name of the file from which a **mesh** or a **gmsh** is loaded. For mesh, the file extentsion is used to determine the file format. Supported formats are the same as in :ref:`mesh assets`. For gmsh, the file is - expected to be in GMSH format 4.1, ascii or binary. + expected to be in GMSH format 4.1 or 2.2, ascii or binary, see :ref:`here`. .. _body-flexcomp-rigid: diff --git a/doc/changelog.rst b/doc/changelog.rst index 6c8e2b5a..940f74f2 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -5,16 +5,20 @@ Changelog Upcoming version (not yet released) ----------------------------------- +General +^^^^^^^ +1. Added support for gmsh format 2.2, as generated by e.g. `fTetwild `__. + MJX ^^^ -1. Improved performance of SAT for convex collisions. -2. Fixed bug for sphere/capsule-convex deep penetration. -3. Fixed bug where ``mjx.Data`` produced by ``mjx.put_data`` had different treedef than ``mjx.make_data``. -4. Throw an error for margin/gap for convex mesh collisions, since they are not supported. +2. Improved performance of SAT for convex collisions. +3. Fixed bug for sphere/capsule-convex deep penetration. +4. Fixed bug where ``mjx.Data`` produced by ``mjx.put_data`` had different treedef than ``mjx.make_data``. +5. Throw an error for margin/gap for convex mesh collisions, since they are not supported. Version 3.1.3 (March 5th, 2024) ------------------------------------ +------------------------------- General ^^^^^^^ diff --git a/src/user/user_flexcomp.cc b/src/user/user_flexcomp.cc index 3130e39c..e7cabbed 100644 --- a/src/user/user_flexcomp.cc +++ b/src/user/user_flexcomp.cc @@ -12,16 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include "user/user_api.h" -#include "user/user_flexcomp.h" -#include - +#include #include #include #include +#include +#include #include #include -#include #include #include @@ -34,6 +32,7 @@ #include "engine/engine_util_errmem.h" #include "engine/engine_util_misc.h" #include "engine/engine_util_spatial.h" +#include "user/user_flexcomp.h" #include "user/user_model.h" #include "user/user_objects.h" #include "user/user_util.h" @@ -58,6 +57,12 @@ static void ReadFromBuffer(T* dst, const char* src) { } +static void ReadStrFromBuffer(char* dest, const char* src, int maxlen) { + std::strncpy(dest, src, maxlen); +} + + + // constructor: set defaults outside mjCDef mjCFlexcomp::mjCFlexcomp(void) { type = mjFCOMPTYPE_GRID; @@ -87,12 +92,12 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) { mjCModel* model = (mjCModel*)spec->element; mjsFlex* dflex = def.spec.flex; int dim = dflex->dim; - bool radial = (type==mjFCOMPTYPE_BOX || - type==mjFCOMPTYPE_CYLINDER || - type==mjFCOMPTYPE_ELLIPSOID); - bool direct = (type==mjFCOMPTYPE_DIRECT || - type==mjFCOMPTYPE_MESH || - type==mjFCOMPTYPE_GMSH); + bool radial = (type == mjFCOMPTYPE_BOX || + type == mjFCOMPTYPE_CYLINDER || + type == mjFCOMPTYPE_ELLIPSOID); + bool direct = (type == mjFCOMPTYPE_DIRECT || + type == mjFCOMPTYPE_MESH || + type == mjFCOMPTYPE_GMSH); // check parent body name if (std::string(mjs_getString(body->name)).empty()) { @@ -100,13 +105,13 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) { } // check dim - if (dim<1 || dim>3) { + if (dim < 1 || dim > 3) { return comperr(error, "Invalid dim, must be between 1 and 3", error_sz); } // check counts - for (int i=0; i<3; i++) { - if (count[i]<1 || ((radial && count[i]<2) && dim==3)) { + for (int i=0; i < 3; i++) { + if (count[i] < 1 || ((radial && count[i] < 2) && dim == 3)) { return comperr(error, "Count too small", error_sz); } } @@ -114,9 +119,9 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) { // check spacing double minspace = 2*dflex->radius + dflex->margin; if (!direct) { - if (spacing[0]flatskin = true; } @@ -190,10 +195,10 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) { if (pingridrange.size()%(2*dim)) { return comperr(error, "Pin grid range number of must be multiple of 2*dim", error_sz); } - if (type!=mjFCOMPTYPE_GRID && !(pingrid.empty() && pingridrange.empty())) { + if (type != mjFCOMPTYPE_GRID && !(pingrid.empty() && pingridrange.empty())) { return comperr(error, "Pin grid(range) can only be used with grid type", error_sz); } - if (dim==1 && !(pingrid.empty() && pingridrange.empty())) { + if (dim == 1 && !(pingrid.empty() && pingridrange.empty())) { return comperr(error, "Pin grid(range) cannot be used with dim=1", error_sz); } @@ -216,8 +221,8 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) { int npnt = point.size()/3; // check elem vertex ids - for (int i=0; i<(int)element.size(); i++) { - if (element[i]<0 || element[i]>=npnt) { + for (int i=0; i < (int)element.size(); i++) { + if (element[i] < 0 || element[i] >= npnt) { char msg[100]; snprintf(msg, sizeof(msg), "element %d has point id %d, number of points is %d", i, element[i], npnt); @@ -226,8 +231,8 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) { } // apply scaling for direct types - if (direct && (scale[0]!=1 || scale[1]!=1 || scale[2]!=1)) { - for (int i=0; i=npnt) { + if (pinid[i] < 0 || pinid[i] >= npnt) { return comperr(error, "pinid out of range", error_sz); } @@ -263,58 +268,58 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) { } // process pinrange - for (int i=0; i<(int)pinrange.size(); i+=2) { + for (int i=0; i < (int)pinrange.size(); i+=2) { // check range - if (pinrange[i]<0 || pinrange[i]>=npnt || - pinrange[i+1]<0 || pinrange[i+1]>=npnt) { + if (pinrange[i] < 0 || pinrange[i] >= npnt || + pinrange[i+1] < 0 || pinrange[i+1] >= npnt) { return comperr(error, "pinrange out of range", error_sz); } // set - for (int k=pinrange[i]; k<=pinrange[i+1]; k++) { + for (int k=pinrange[i]; k <= pinrange[i+1]; k++) { pinned[k] = true; } } // process pingrid - for (int i=0; i<(int)pingrid.size(); i+=dim) { + for (int i=0; i < (int)pingrid.size(); i+=dim) { // check range - for (int k=0; k=count[k]) { + for (int k=0; k < dim; k++) { + if (pingrid[i+k] < 0 || pingrid[i+k] >= count[k]) { return comperr(error, "pingrid out of range", error_sz); } } // set - if (dim==2) { + if (dim == 2) { pinned[GridID(pingrid[i], pingrid[i+1])] = true; } - else if (dim==3) { + else if (dim == 3) { pinned[GridID(pingrid[i], pingrid[i+1], pingrid[i+2])] = true; } } // process pingridrange - for (int i=0; i<(int)pingridrange.size(); i+=2*dim) { + for (int i=0; i < (int)pingridrange.size(); i+=2*dim) { // check range - for (int k=0; k<2*dim; k++) { - if (pingridrange[i+k]<0 || pingridrange[i+k]>=count[k%dim]) { + for (int k=0; k < 2*dim; k++) { + if (pingridrange[i+k] < 0 || pingridrange[i+k] >= count[k%dim]) { return comperr(error, "pingridrange out of range", error_sz); } } // set - if (dim==2) { - for (int ix=pingridrange[i]; ix<=pingridrange[i+2]; ix++) { - for (int iy=pingridrange[i+1]; iy<=pingridrange[i+3]; iy++) { + if (dim == 2) { + for (int ix=pingridrange[i]; ix <= pingridrange[i+2]; ix++) { + for (int iy=pingridrange[i+1]; iy <= pingridrange[i+3]; iy++) { pinned[GridID(ix, iy)] = true; } } } else if (dim==3) { - for (int ix=pingridrange[i]; ix<=pingridrange[i+3]; ix++) { - for (int iy=pingridrange[i+1]; iy<=pingridrange[i+4]; iy++) { - for (int iz=pingridrange[i+2]; iz<=pingridrange[i+5]; iz++) { + for (int ix=pingridrange[i]; ix <= pingridrange[i+3]; ix++) { + for (int iy=pingridrange[i+1]; iy <= pingridrange[i+4]; iy++) { + for (int iz=pingridrange[i+2]; iz <= pingridrange[i+5]; iz++) { pinned[GridID(ix, iy, iz)] = true; } } @@ -329,7 +334,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) { // check if all or none are pinned bool allpin = true, nopin = true; - for (int i=0; i (npnt, false); - for (int i=0; i<(int)element.size(); i++) { + for (int i=0; i < (int)element.size(); i++) { used[element[i]] = true; } // construct reindex bool hasunused = false; std::vector reindex (npnt, 0); - for (int i=0; i0 && iz0 && iz < count[2]-1) { BoxProject(pos, ix, iy, iz); point.push_back(pos[0]); point.push_back(pos[1]); @@ -795,7 +800,7 @@ bool mjCFlexcomp::MakeBox(char* error, int error_sz) { } // add elements - if (ix0 && iz0 && iy 0 && iz < count[2]-1 && iy > 0 && iy < count[1]-1) { BoxProject(pos, ix, iy, iz); point.push_back(pos[0]); point.push_back(pos[1]); @@ -823,7 +828,7 @@ bool mjCFlexcomp::MakeBox(char* error, int error_sz) { } // add elements - if (iydim!=2) { + if (def.spec.flex->dim != 2) { return comperr(error, "Flex dim must be 2 in for mesh", error_sz); } @@ -943,7 +948,7 @@ bool mjCFlexcomp::MakeMesh(mjCModel* model, char* error, int error_sz) { // copy vertices, convert from float to mjtNum point = vector (mesh.nvert()*3); - for (int i=0; i> numEntityBlocks >> numNodes >> minNodeTag >> maxNodeTag; @@ -1087,31 +1046,31 @@ void mjCFlexcomp::LoadGMSH(mjCModel* model, mjResource* resource) { } // require single block - if (numEntityBlocks!=1 || numNodes!=numNodesInBlock) { + if (numEntityBlocks != 1 || numNodes != numNodesInBlock) { throw mjCError(NULL, "All nodes must be in single block"); } // check dimensionality and save - if (entityDim<1 || entityDim>3) { + if (entityDim < 1 || entityDim > 3) { throw mjCError(NULL, "Entity must be 1D, 2D or 3D"); } def.spec.flex->dim = entityDim; // read and discard node tags; require range from minNodeTag to maxNodeTag - for (size_t i=0; i> tag; if (!ss.good()) { throw mjCError(NULL, "Error reading node tags"); } - if (tag!=i+minNodeTag) { + if (tag != i+minNodeTag) { throw mjCError(NULL, "Node tags must be sequential"); } } // read points point.reserve(3*numNodes); - for (size_t i=0; i<3*numNodes; i++) { + for (size_t i=0; i < 3*numNodes; i++) { double x; ss >> x; if (!ss.good()) { @@ -1120,45 +1079,49 @@ void mjCFlexcomp::LoadGMSH(mjCModel* model, mjResource* resource) { point.push_back(x); } } - // binary nodes else { - // check header size: 5 size_t, 3 int - if (nodeend-nodebegin < 52) { + // check header size + if (nodeend-nodebegin < kGmsh41HeaderSize) { throw mjCError(NULL, "Invalid nodes header"); } // read header - ReadFromBuffer(&numEntityBlocks, buffer+nodebegin); - ReadFromBuffer(&numNodes, buffer+nodebegin+8); - ReadFromBuffer(&minNodeTag, buffer+nodebegin+16); - ReadFromBuffer(&maxNodeTag, buffer+nodebegin+24); - ReadFromBuffer(&entityDim, buffer+nodebegin+32); - ReadFromBuffer(&entityTag, buffer+nodebegin+36); - ReadFromBuffer(¶metric, buffer+nodebegin+40); - ReadFromBuffer(&numNodesInBlock, buffer+nodebegin+44); + ReadFromBuffer(&numEntityBlocks, buffer + nodebegin); + ReadFromBuffer(&numNodes, buffer + nodebegin + 8); + ReadFromBuffer(&minNodeTag, buffer + nodebegin + 16); + ReadFromBuffer(&maxNodeTag, buffer + nodebegin + 24); + ReadFromBuffer(&entityDim, buffer + nodebegin + 32); + ReadFromBuffer(&entityTag, buffer + nodebegin + 36); + ReadFromBuffer(¶metric, buffer + nodebegin + 40); + ReadFromBuffer(&numNodesInBlock, buffer + nodebegin + 44); // require single block - if (numEntityBlocks!=1 || numNodes!=numNodesInBlock) { + if (numEntityBlocks != 1 || numNodes != numNodesInBlock) { throw mjCError(NULL, "All nodes must be in single block"); } // check dimensionality and save - if (entityDim<1 || entityDim>3) { + if (entityDim < 1 || entityDim > 3) { throw mjCError(NULL, "Entity must be 1D, 2D or 3D"); } def.spec.flex->dim = entityDim; + // nodeData: node tag and 3 nodes + constexpr int numNodeComponents = 4; + constexpr int componentSize = 8; + int nodeDataSize = numNodeComponents*componentSize; + // check section byte size - if (nodeend-nodebegin < 52+numNodes*4*8) { + if (nodeend-nodebegin < kGmsh41HeaderSize + numNodes*nodeDataSize) { throw mjCError(NULL, "Insufficient byte size of Nodes"); } // check node tags: must range from minNodeTag to maxNodeTag - const char* tagbuffer = buffer + nodebegin + 52; - for (size_t i=0; i> numEntityBlocks >> numElements >> minElementTag >> maxElementTag; @@ -1190,28 +1153,28 @@ void mjCFlexcomp::LoadGMSH(mjCModel* model, mjResource* resource) { } // require single block - if (numEntityBlocks!=1 || numElements!=numElementsInBlock) { + if (numEntityBlocks != 1 || numElements != numElementsInBlock) { throw mjCError(NULL, "All elements must be in single block"); } // dimensionality must be same as nodes - if (entityDim!=def.spec.flex->dim) { + if (entityDim != def.spec.flex->dim) { throw mjCError(NULL, "Inconsistent dimensionality in Elements"); } // type must be consistent with dimensionality - if ((entityDim==1 && elementType!=1) || - (entityDim==2 && elementType!=2) || - (entityDim==3 && elementType!=4)) { + if ((entityDim == 1 && elementType != 1) || + (entityDim == 2 && elementType != 2) || + (entityDim == 3 && elementType != 4)) { throw mjCError(NULL, "Element type inconsistent with dimensionality"); } // read elements, discard tags element.reserve((entityDim+1)*numElements); - for (size_t i=0; i> tag; - for (int k=0; k<=entityDim; k++) { + for (int k=0; k <= entityDim; k++) { ss >> nodeid; if (!ss.good()) { throw mjCError(NULL, "Error reading Elements"); @@ -1223,58 +1186,355 @@ void mjCFlexcomp::LoadGMSH(mjCModel* model, mjResource* resource) { // binary elements else { - // check header size: 5 size_t, 3 int - if (elemend-elembegin < 52) { + // check header size + if (elemend-elembegin < kGmsh41HeaderSize) { throw mjCError(NULL, "Invalid elements header"); } // read header - ReadFromBuffer(&numEntityBlocks, buffer+elembegin); - ReadFromBuffer(&numElements, buffer+elembegin+8); - ReadFromBuffer(&minElementTag, buffer+elembegin+16); - ReadFromBuffer(&maxElementTag, buffer+elembegin+24); - ReadFromBuffer(&entityDim, buffer+elembegin+32); - ReadFromBuffer(&entityTag, buffer+elembegin+36); - ReadFromBuffer(&elementType, buffer+elembegin+40); - ReadFromBuffer(&numElementsInBlock, buffer+elembegin+44); + ReadFromBuffer(&numEntityBlocks, buffer + elembegin); + ReadFromBuffer(&numElements, buffer + elembegin + 8); + ReadFromBuffer(&minElementTag, buffer + elembegin + 16); + ReadFromBuffer(&maxElementTag, buffer + elembegin + 24); + ReadFromBuffer(&entityDim, buffer + elembegin + 32); + ReadFromBuffer(&entityTag, buffer + elembegin + 36); + ReadFromBuffer(&elementType, buffer + elembegin + 40); + ReadFromBuffer(&numElementsInBlock, buffer + elembegin + 44); // require single block - if (numEntityBlocks!=1 || numElements!=numElementsInBlock) { + if (numEntityBlocks != 1 || numElements != numElementsInBlock) { throw mjCError(NULL, "All elements must be in single block"); } // dimensionality must be same as nodes - if (entityDim!=def.spec.flex->dim) { + if (entityDim != def.spec.flex->dim) { throw mjCError(NULL, "Inconsistent dimensionality in Elements"); } // type must be consistent with dimensionality - if ((entityDim==1 && elementType!=1) || - (entityDim==2 && elementType!=2) || - (entityDim==3 && elementType!=4)) { + if ((entityDim == 1 && elementType != 1) || + (entityDim == 2 && elementType != 2) || + (entityDim == 3 && elementType != 4)) { throw mjCError(NULL, "Element type inconsistent with dimensionality"); } + // elementData: element tag and n node tags + int numElementComponents = (entityDim+2); + constexpr int componentSize = 8; + int elementDataSize = numElementComponents*componentSize; + // check section byte size - if (elemend-elembegin < 52+numElements*(entityDim+2)*8) { + if (elemend - elembegin < kGmsh41HeaderSize + numElements*elementDataSize) { throw mjCError(NULL, "Insufficient byte size of Elements"); } // read elements, discard tags element.reserve((entityDim+1)*numElements); - const char* elembuffer = buffer + elembegin + 52; - for (size_t i=0; i> maxNodeTag; + if (!ss.good()) { + throw mjCError(NULL, "Error reading Nodes header"); + } + size_t numNodes = maxNodeTag; + + // read points, discard tag + point.reserve(3*numNodes); + for (size_t i=0; i < numNodes; i++) { + size_t tag; + double x; + ss >> tag; + if (!ss.good()) { + throw mjCError(NULL, "Error reading node tags"); + } + // reading nodes + for (int k=0; k < 3; k++) { + ss >> x; + if (!ss.good()) { + throw mjCError(NULL, "Error reading node coordinates"); + } + point.push_back(x); + } + } + } + + // binary nodes + else { + // header size for gmshApp + constexpr int nodeHeaderSizeGmshApp = 5; + // header size compatible with both gmshApp and Ftetwild + constexpr int nodeHeaderSize = nodeHeaderSizeGmshApp - 1; + // check header size + if (nodeend-nodebegin < nodeHeaderSize) { + throw mjCError(NULL, "Invalid nodes header"); + } + + // parse maxNodeTag and then cast it to int + char maxNodeTagChar[20]; + ReadStrFromBuffer(maxNodeTagChar, buffer + nodebegin, std::min(10, nodeend - nodebegin)); + size_t measuredHeaderSize = strnlen(maxNodeTagChar, 20) - 1; + size_t maxNodeTag = std::stoi(maxNodeTagChar); + size_t numNodes = maxNodeTag; + + // node data: node tag and 3 nodes + int nodeSize = sizeof(double); + int indexSize = sizeof(int); + int nodeDataSize = indexSize + 3*nodeSize; + + // check section byte size + if (nodeend - nodebegin < nodeHeaderSize + numNodes*nodeDataSize) { + throw mjCError(NULL, "Insufficient byte size of Nodes"); + } + + // read point, discard tag + point.reserve(3*numNodes); + // beginning of buffer containing node info + const char* tagBuffer = buffer + nodebegin + measuredHeaderSize; + for (int i=0; i < numNodes; i++) { + int tag; + int offset = i*(sizeof(int) + sizeof(double)*3); + ReadFromBuffer(&tag, tagBuffer + offset); + for (int k=0; k < 3; k++) { + double x; + const char* nodeBuffer = tagBuffer + sizeof(int) + sizeof(double)*k; + ReadFromBuffer(&x, nodeBuffer + offset); + point.push_back(x); + } + } + } + + size_t entityDim = 3; + def.spec.flex->dim = entityDim; + + // ascii elements + if (binary == 0) { + // convert element char buffer to stringstream + buffer[elemend] = 0; + stringstream ss(buffer + elembegin); + + // read header + size_t maxElementTag = 0; + ss >> maxElementTag; + if (!ss.good()) { + throw mjCError(NULL, "Error reading Elements header"); + } + size_t numElements = maxElementTag; + // read elements, discard all tags + element.reserve((entityDim+1)*numElements); + for (size_t i=0; i < numElements; i++) { + int tag = 0, type = 0, numTags = 0, nodeTag = 0, physicalEntityTag = 0, + elmentModelEntityTag = 0; + ss >> tag >> type >> numTags; + if (!ss.good()) { + throw mjCError(NULL, "Error reading Elements"); + } + if (numTags > 0) { + ss >> physicalEntityTag >> elmentModelEntityTag; + if (!ss.good()) { + throw mjCError(NULL, "Error reading Elements"); + } + } + for (int k=0; k <= entityDim; k++) { + ss >> nodeTag; + if (!ss.good()) { + throw mjCError(NULL, "Error reading Elements"); + } + element.push_back((int)(nodeTag-1)); + } + } + } + // binary elements + else { + // header size for gmshApp + constexpr int elementHeaderSizeGmshApp = 6; + // header size for Ftetwild + constexpr int elementHeaderSizeFtetwild = 17; + // check header size + if (elemend - elembegin < elementHeaderSizeGmshApp) { + throw mjCError(NULL, "Invalid elements header"); + } + + // reading elements + char maxElementTagChar[20]; + ReadStrFromBuffer(maxElementTagChar, buffer + elembegin, std::min(10, elemend - elembegin)); + int measuredHeaderSize = strnlen(maxElementTagChar, 20) - 1; + int maxElementTag = std::stoi(maxElementTagChar); + int numElements = maxElementTag; + int tag, numTags; + int nodeTag; + + // size of single component in element data + int componentSize = sizeof(int); + // element buffer + const char* elementsBuffer = buffer + elembegin + measuredHeaderSize; + + ReadFromBuffer(&numTags, elementsBuffer + componentSize*2); + ReadFromBuffer(&tag, elementsBuffer + componentSize*3); + + // element data(Ftetwild): tag and 4 nodeTag + constexpr int numComponentsFtetwild = 5; + // element data(gmshApp): 4 Info components, 2 entity tag and 4 nodeTags + constexpr int numInfoComponents = 4; + constexpr int numEntityTagComponents = 2; + constexpr int numNodeTags = 4; + constexpr int numComponentsGmshApp = numInfoComponents + + numEntityTagComponents + numNodeTags; + + // single element data size + int elementDataSizeFtetwild = numComponentsFtetwild*componentSize; + int elementDataSizeGmshApp = numComponentsGmshApp*componentSize; + + // elements section buffer size + int elementsBufferSizeFtetwild = elementHeaderSizeFtetwild + + numElements*elementDataSizeFtetwild; + int elementsBufferSizeGmshApp = elementHeaderSizeGmshApp + + numElements*elementDataSizeGmshApp; + + // check section byte size for ftetwild + if (elemend - elembegin < elementsBufferSizeFtetwild) { + throw mjCError(NULL, "Insufficient byte size of Elements"); + } + + // Handling elements produced by gmsh + if (numTags > 0) { + // check section byte size for gmsh + if (elemend - elembegin < elementsBufferSizeGmshApp) { + throw mjCError(NULL, "Insufficient byte size of Elements"); + } + + // read first element + for (int k =0; k + diff --git a/test/user/testdata/malformed_shark_22_ascii_missing_node.xml b/test/user/testdata/malformed_shark_22_ascii_missing_node.xml new file mode 100644 index 00000000..0d615899 --- /dev/null +++ b/test/user/testdata/malformed_shark_22_ascii_missing_node.xml @@ -0,0 +1,27 @@ + + diff --git a/test/user/testdata/malformed_shark_22_ascii_missing_num_elements.xml b/test/user/testdata/malformed_shark_22_ascii_missing_num_elements.xml new file mode 100644 index 00000000..61015b92 --- /dev/null +++ b/test/user/testdata/malformed_shark_22_ascii_missing_num_elements.xml @@ -0,0 +1,27 @@ + + diff --git a/test/user/testdata/malformed_shark_22_ascii_missing_num_nodes.xml b/test/user/testdata/malformed_shark_22_ascii_missing_num_nodes.xml new file mode 100644 index 00000000..f29ea403 --- /dev/null +++ b/test/user/testdata/malformed_shark_22_ascii_missing_num_nodes.xml @@ -0,0 +1,27 @@ + + diff --git a/test/user/testdata/malformed_shark_41_ascii_missing_element.xml b/test/user/testdata/malformed_shark_41_ascii_missing_element.xml new file mode 100644 index 00000000..2a32b08f --- /dev/null +++ b/test/user/testdata/malformed_shark_41_ascii_missing_element.xml @@ -0,0 +1,27 @@ + + diff --git a/test/user/testdata/malformed_shark_41_ascii_missing_element_header.xml b/test/user/testdata/malformed_shark_41_ascii_missing_element_header.xml new file mode 100644 index 00000000..9d462cda --- /dev/null +++ b/test/user/testdata/malformed_shark_41_ascii_missing_element_header.xml @@ -0,0 +1,27 @@ + + diff --git a/test/user/testdata/malformed_shark_41_ascii_missing_node_header.xml b/test/user/testdata/malformed_shark_41_ascii_missing_node_header.xml new file mode 100644 index 00000000..a54cda88 --- /dev/null +++ b/test/user/testdata/malformed_shark_41_ascii_missing_node_header.xml @@ -0,0 +1,27 @@ + + diff --git a/test/user/testdata/malformed_shark_41_ascii_missing_node_index.xml b/test/user/testdata/malformed_shark_41_ascii_missing_node_index.xml new file mode 100644 index 00000000..5e810d10 --- /dev/null +++ b/test/user/testdata/malformed_shark_41_ascii_missing_node_index.xml @@ -0,0 +1,27 @@ + + diff --git a/test/user/testdata/shark_22_ascii_fTetWild.msh b/test/user/testdata/shark_22_ascii_fTetWild.msh new file mode 100644 index 00000000..323ae997 --- /dev/null +++ b/test/user/testdata/shark_22_ascii_fTetWild.msh @@ -0,0 +1,3979 @@ +$MeshFormat +2.2 0 8 +$EndMeshFormat +$Nodes +652 +1 -0.0733436 0.0816748 0.056402 +2 -0.0729126 0.0537921 0.00170478 +3 -0.072634 0.0799069 0.0578949 +4 -0.0715817 0.0520377 0.00292576 +5 -0.0701949 0.0802569 0.0450431 +6 -0.0687698 0.060971 0.00326551 +7 -0.06778 0.060358 0.00473741 +8 -0.0672796 0.0809249 0.0425553 +9 -0.0658074 0.0806443 0.0552302 +10 -0.064933 0.0788176 0.0453762 +11 -0.0636555 0.0610198 0.00141989 +12 -0.0636111 0.0566004 -0.000556663 +13 -0.0636791 0.0819076 0.0524468 +14 -0.0623445 0.0580268 0.00335683 +15 -0.0624856 0.0671058 0.00581638 +16 -0.0601398 0.0781111 0.0317589 +17 -0.0599443 0.0685632 0.00992449 +18 -0.0592787 0.0571239 0.00105116 +19 -0.0587906 0.0719999 0.0117948 +20 -0.0575605 0.0730663 0.016213 +21 -0.057624 0.0811803 0.0403639 +22 -0.0572339 0.0769387 0.0223219 +23 -0.0559974 0.0749629 0.0235691 +24 -0.0542321 0.0763209 0.0344665 +25 -0.0540672 0.0649483 0.00821813 +26 -0.0541685 0.0661135 0.00437935 +27 -0.0532966 0.0805356 0.0466758 +28 -0.0517252 0.0761185 0.0183218 +29 -0.0505257 0.068877 0.0152572 +30 -0.0503803 0.0772638 0.0406423 +31 -0.0472855 0.0641041 0.00381053 +32 -0.0469016 0.0648796 0.00821733 +33 -0.0474599 0.0727268 0.0265623 +34 -0.0464733 0.070912 0.0103373 +35 -0.0444756 0.0755674 0.0221683 +36 -0.0440208 0.0774313 0.0371107 +37 -0.0434135 0.0685101 0.0213943 +38 -0.0425401 0.0668787 0.0159114 +39 -0.0405353 0.0730163 0.0309862 +40 -0.0386417 0.073548 0.0160682 +41 -0.037401 0.0664899 0.0122191 +42 -0.0358693 0.0689445 0.0243885 +43 -0.0351058 0.0687771 0.0124837 +44 -0.0333614 0.071165 0.0238503 +45 -0.0325564 0.0696271 0.024504 +46 -0.032455 0.0625178 0.0200737 +47 -0.0305469 0.0729973 0.0173921 +48 -0.0276941 0.0652386 0.0128238 +49 -0.0272717 0.0628782 0.0141328 +50 -0.0263428 0.00735496 0.00505748 +51 -0.0256055 0.00658056 0.00327552 +52 -0.0252856 0.0610141 0.0227762 +53 -0.0250237 -0.00678856 0.00359213 +54 -0.0242889 -0.00589458 0.00589675 +55 -0.0216872 0.0639735 0.0255561 +56 -0.0215721 -0.0119744 0.00619585 +57 -0.0195136 0.0542304 0.0216195 +58 -0.0168343 0.0649534 0.0236547 +59 -0.0161373 -0.00420129 0.00881529 +60 -0.0148726 0.0585475 0.0106707 +61 -0.0140647 0.0517836 0.0159197 +62 -0.0142986 0.0543801 0.0051496 +63 -0.0139611 -0.0178642 0.00651265 +64 -0.0139803 0.0554055 0.0115694 +65 -0.0124373 0.0606817 0.0122622 +66 -0.0127423 0.0580719 0.0285553 +67 -0.0127412 -0.0704232 0.0234664 +68 -0.0126173 -0.0801905 0.022154 +69 -0.0125269 0.0592002 0.0346418 +70 -0.0122498 -0.080596 0.0191154 +71 -0.0121442 -0.0691943 0.0191352 +72 -0.0123618 0.0658492 0.0197519 +73 -0.0121018 -0.063334 0.0245151 +74 -0.0118539 0.0462485 0.0243954 +75 -0.0111067 0.0637388 0.0161162 +76 -0.0110042 -0.0624802 0.0276395 +77 -0.0109072 0.046219 0.0183571 +78 -0.0107037 -0.000325242 0.00950432 +79 -0.010183 -0.0121386 0.00674337 +80 -0.00977442 -0.0638147 0.0162637 +81 -0.0097669 -0.0699334 0.0156591 +82 -0.00942656 -0.0836042 0.0182705 +83 -0.009321 -0.0852334 0.0216727 +84 -0.00803502 0.0401179 0.0263407 +85 -0.00857808 -0.0579335 0.0163943 +86 -0.00793158 -0.0190616 0.0121625 +87 -0.00782675 0.0573514 0.028038 +88 -0.00773028 -0.0620746 0.0302044 +89 -0.00764665 0.0537773 0.00961295 +90 -0.00721562 -0.0507362 0.0224357 +91 -0.00717408 -0.0528249 0.0179333 +92 -0.00651588 -0.00739691 0.013024 +93 -0.00691116 -0.00014073 0.00823716 +94 -0.00661131 0.044183 0.0123 +95 -0.00658663 0.0535365 0.0326225 +96 -0.00630954 -0.0850657 0.0194796 +97 -0.00616497 -0.0797841 0.0261073 +98 -0.00582999 -0.0494502 0.0287705 +99 -0.00563359 0.0476479 0.00934546 +100 -0.00506609 -0.0425596 0.0250833 +101 -0.00453974 -0.0405694 0.0173853 +102 -0.00447266 0.0319291 0.0205877 +103 -0.00434886 0.0267225 0.00648417 +104 -0.00418386 0.0253438 0.00842196 +105 -0.0041733 -0.0606038 0.0122716 +106 -0.00385183 0.0479538 0.00869149 +107 -0.00333705 0.051389 0.031593 +108 -0.00333565 -0.0693881 0.0119551 +109 -0.00333748 -0.0650683 0.0110291 +110 -0.00292457 0.0475597 0.0319288 +111 -0.00280471 -0.0353375 0.0238411 +112 -0.00273019 -0.0493159 0.0135756 +113 -0.00255346 -0.0452657 0.0126112 +114 -0.00249178 -0.0598565 0.010934 +115 -0.00247351 -0.0533955 0.0149632 +116 -0.00280465 0.0288144 0.0300227 +117 -0.00225175 -0.030519 0.0236922 +118 -0.00205777 -0.0595101 0.00715068 +119 -0.0018581 -0.0627033 0.0116048 +120 -0.00150112 -0.0384203 0.0313885 +121 -0.00143547 -0.0337232 0.0176227 +122 -0.00136747 -0.062725 0.0150152 +123 -0.000884775 -0.0587825 0.0143119 +124 -0.000624659 -0.0247814 0.0257906 +125 -0.000489974 0.0225414 0.0188523 +126 -6.05566e-05 0.0171338 0.0234086 +127 0.00150381 0.0360475 0.00675461 +128 0.000282178 -0.0241462 0.0174969 +129 0.000347869 -0.0675237 0.0324883 +130 0.000429839 -0.0422219 0.0349169 +131 0.00028168 -0.0273698 0.0312235 +132 0.000952705 -0.0267391 0.0143612 +133 0.00105244 0.0186951 0.00689988 +134 0.0011109 -0.0779453 0.014663 +135 0.00137887 0.00842564 0.0258445 +136 0.00107238 -0.0462225 0.00980545 +137 0.00158113 -0.0561697 0.005809 +138 0.00165921 -0.0142314 0.0114909 +139 0.00169065 -0.00330978 0.027848 +140 0.0017282 0.0264299 0.00972258 +141 0.00196109 -0.062067 0.0125082 +142 0.00198494 -0.0249792 0.0122768 +143 0.00206797 -0.0322322 0.0125632 +144 0.00219287 -0.00991015 0.0199027 +145 0.00223228 -0.065619 0.00972103 +146 0.00226787 -0.06664 0.0139131 +147 0.00233081 0.00970751 0.0349608 +148 0.0023033 -0.0550711 0.0357611 +149 0.00284591 -0.0695874 0.0109337 +150 0.00313658 0.0123831 0.0152878 +151 0.00325266 -0.000639164 0.0164744 +152 0.00354678 -0.0651674 0.00553443 +153 0.00434877 0.0392681 0.00656793 +154 0.0034004 -0.0624097 0.0143354 +155 0.00410027 0.052311 0.0146156 +156 0.00425687 -0.0110681 0.0377954 +157 0.0043501 -0.0020508 0.015115 +158 0.00444422 -0.0785667 0.0168482 +159 0.00471578 -0.00872746 0.0133588 +160 0.00486541 0.0192794 0.0102326 +161 0.00475235 0.0259901 0.00777948 +162 0.00497525 -0.0797755 0.0244877 +163 0.0052286 0.0545416 0.0234287 +164 0.00513856 -0.0361953 0.00904286 +165 0.00543656 -0.016404 0.0117933 +166 0.00521097 0.0361763 0.0357574 +167 0.00563068 0.0458779 0.0101474 +168 0.00602624 -0.0598053 0.00448538 +169 0.00669265 -0.0730234 0.0300997 +170 0.00671975 -0.0647944 0.0149968 +171 0.00743572 0.0219428 0.00498754 +172 0.00806977 -0.0676622 0.0106835 +173 0.00858002 0.0185363 0.00804532 +174 0.00900922 -0.0527441 0.0382868 +175 0.00967438 -0.0310472 0.0412759 +176 0.00969027 -0.0470756 0.00574739 +177 0.00982547 -0.0777201 0.0238208 +178 0.010337 -0.0646559 0.00738197 +179 0.0103691 -0.0715108 0.0301524 +180 0.0108524 -0.0651923 0.0107074 +181 0.0112352 0.0223598 0.00496048 +182 0.0115762 0.0360388 0.034027 +183 0.011811 0.0150563 0.0411225 +184 0.0119389 -0.0710873 0.0142927 +185 0.011481 0.000850754 0.00890493 +186 0.0122581 0.0177891 0.00726338 +187 0.0126044 0.0285097 0.0071727 +188 0.0126077 -0.0410848 0.00487059 +189 0.01325 0.0245576 0.00385279 +190 0.0133342 -0.0301914 0.00695184 +191 0.0134526 -0.00467313 0.044297 +192 0.0140263 0.0415073 0.0128325 +193 0.0139319 -0.0627506 0.0126489 +194 0.0144402 0.0213321 0.0408733 +195 0.0145153 -0.0120242 0.00709154 +196 0.0145254 0.0314471 0.00762861 +197 0.0143606 -0.0539791 0.00638859 +198 0.0153705 -0.0588177 0.00913193 +199 0.0158483 0.0424843 0.0267153 +200 0.0161677 0.0082135 0.0752128 +201 0.0160709 -0.0693691 0.0267104 +202 0.0163112 0.021127 0.00658374 +203 0.0163956 0.0418119 0.0180916 +204 0.0166653 0.00513625 0.0449469 +205 0.0171438 -0.00939438 0.0462661 +206 0.0174416 -0.0497054 0.0373642 +207 0.0174198 -0.0656937 0.0159871 +208 0.0177387 0.0346114 0.0053358 +209 0.0178439 0.0247259 0.00729322 +210 0.018247 0.0346901 0.00258831 +211 0.0182074 -0.0318958 0.0424624 +212 0.0183988 -0.00142899 0.0496692 +213 0.0188182 -0.018825 0.0447569 +214 0.0188285 0.0147456 0.0461032 +215 0.0188626 0.015416 0.041072 +216 0.0190811 -0.00419709 0.0686858 +217 0.0195945 0.0084326 0.064095 +218 0.0197498 -0.00217441 0.0583864 +219 0.0198208 0.00539755 0.0587622 +220 0.0200137 0.0324539 0.00354185 +221 0.020151 -0.0145671 0.0500049 +222 0.0203386 -0.00326709 0.0702447 +223 0.0209148 0.00523036 0.0681576 +224 0.0208447 0.0121045 0.0546374 +225 0.0209724 0.00970633 0.0633876 +226 0.020604 -0.0121123 0.00591309 +227 0.0212498 -0.0289526 0.00565549 +228 0.0216078 -0.0380775 0.00479088 +229 0.0216875 -0.00997672 0.0619769 +230 0.0220658 0.00705093 0.0456869 +231 0.0223002 -0.0558455 0.0110476 +232 0.0223137 -0.0154618 0.0494217 +233 0.0229336 0.00417573 0.0589573 +234 0.0231427 0.0278288 0.0125965 +235 0.0231751 0.027241 0.0309726 +236 0.0233259 0.0160686 0.00756079 +237 0.0234095 0.0318943 0.0199392 +238 0.0234462 -0.00393483 0.0583985 +239 0.0235915 -0.0597066 0.0170609 +240 0.0240196 -0.0108777 0.0466362 +241 0.024123 -0.00330273 0.0464733 +242 0.0242099 -0.0321428 0.0398591 +243 0.0244244 0.00347947 0.0416421 +244 0.024564 -0.0175604 0.0433407 +245 0.0253979 -0.0453083 0.0344803 +246 0.0256103 0.0267734 0.0284514 +247 0.0259312 -0.0445208 0.00878379 +248 0.025959 -0.0133125 0.00624018 +249 0.0265967 -0.0369666 0.00635268 +250 0.0273245 -0.0066598 0.0412078 +251 0.0277597 -0.0467651 0.0304517 +252 0.0275944 -0.0515878 0.0207552 +253 0.0282687 0.0208205 0.0174814 +254 0.0290859 0.0112094 0.012597 +255 0.0293048 -0.0474855 0.0256026 +256 0.0296506 -0.0466043 0.0156453 +257 0.0304236 0.0134394 0.031696 +258 0.0304518 -0.0291908 0.00746031 +259 0.03126 -0.044124 0.016095 +260 0.0321715 -0.043346 0.0242104 +261 0.0322352 -0.0402733 0.0141242 +262 0.0323149 0.01052 0.0200521 +263 0.0324768 -0.0397188 0.0271188 +264 0.0325431 -0.0291932 0.0340382 +265 0.0332479 -0.0329826 0.0117351 +266 0.0338676 -0.0346121 0.0252676 +267 0.0341522 -0.00293196 0.033596 +268 0.0341882 -0.0361716 0.0179088 +269 0.0344969 -0.0256263 0.0309923 +270 0.0345138 -0.00958586 0.0123416 +271 0.0348872 -0.0128566 0.0339912 +272 0.0349524 -0.0273994 0.0177976 +273 0.0349556 -0.000677158 0.0209767 +274 0.0350004 -0.028049 0.00876142 +275 0.0353194 -0.0100316 0.0154749 +276 0.0354214 -0.0195455 0.0173172 +277 0.0355775 -0.0309821 0.0107592 +278 0.0360305 -0.0150581 0.0232372 +279 0.0363938 -0.0285041 0.0132933 +280 0.0374738 -0.00607371 0.0123945 +281 0.041317 -0.0210454 0.0131228 +282 0.0425886 -0.0120136 0.0129537 +283 0.0475164 -0.00753527 0.00853843 +284 0.0492593 -0.00704914 0.00938067 +285 0.0496752 -0.0170405 0.0106038 +286 0.0498676 -0.0259318 0.00619626 +287 0.052402 -0.022331 0.00866719 +288 0.0516897 -0.011391 0.0103437 +289 0.0559595 -0.0106346 0.00698866 +290 0.0596531 -0.0214295 0.0059579 +291 0.066312 -0.0158462 0.00759335 +292 0.0672852 -0.00331292 0.00667068 +293 0.0687074 -0.0027598 0.00829441 +294 0.0687083 -0.0084515 0.00881385 +295 0.0702857 -0.00694567 0.00665748 +296 0.02471 0.00101921 0.00688758 +297 0.00641783 -0.0341512 0.0233596 +298 0.024018 0.00854392 0.00722419 +299 0.0251696 0.00942127 0.00784613 +300 -0.019815 0.0686939 0.0189821 +301 0.0416697 -0.017118 0.00864259 +302 -0.00440288 -0.0698432 0.0205811 +303 -0.0033606 0.0600219 0.0217676 +304 0.0268544 0.00322876 0.0080825 +305 0.00855449 0.0107052 0.00928038 +306 0.0219179 0.00585482 0.0121236 +307 0.0199208 0.0175811 0.0336776 +308 0.0210521 -0.0362113 0.0256186 +309 0.0339797 -0.00194129 0.0163861 +310 0.03202 0.000337126 0.0126992 +311 0.0119633 0.0163586 0.0147908 +312 0.0248778 0.0056119 0.0321775 +313 0.00892971 -0.0563678 0.0287948 +314 0.0174837 0.027107 0.0210333 +315 -0.0170518 0.00346089 0.00554363 +316 0.0144974 -0.0120686 0.0314959 +317 0.00336155 -0.00103205 0.0364574 +318 0.00707711 -0.0204903 0.0185209 +319 0.010517 -0.00309481 0.0232445 +320 -0.00559352 0.0373259 0.0172753 +321 -0.00523735 -0.0230725 0.0111224 +322 0.0151072 -0.0538804 0.0213778 +323 0.0347571 -0.0188174 0.0105515 +324 0.0278657 -0.0183642 0.0156758 +325 -0.00338013 -0.0543805 0.0329679 +326 -0.0196332 0.0593213 0.0251138 +327 0.0648163 -0.0143432 0.00627944 +328 -0.00336175 -0.0187472 0.00979996 +329 -0.0059938 -0.0214388 0.00941436 +330 0.0204933 0.0262773 0.00994486 +331 0.0153554 0.00838654 0.0105168 +332 -0.064082 0.064994 0.00682263 +333 -0.0406296 0.0703091 0.0249838 +334 -0.0197677 0.0563929 0.0156108 +335 -0.0506931 0.0781816 0.0304629 +336 0.0171972 -0.00100568 0.011485 +337 0.0314619 -0.0225976 0.00774901 +338 -0.00980694 0.0515267 0.0104574 +339 -0.00435185 0.0493969 0.0137744 +340 0.0449063 -0.0117353 0.00859937 +341 0.00159087 -0.0450385 0.027858 +342 -0.00469537 -0.0637251 0.0233918 +343 0.0424219 -0.0285632 0.00857374 +344 0.0603894 -0.00835109 0.00935053 +345 -0.0147113 -0.0156046 0.00918376 +346 -0.0528157 0.0611754 0.00480955 +347 -0.0173765 -0.00887149 0.00520522 +348 0.0108104 0.02268 0.0130558 +349 -0.00899905 -0.0208443 0.00915416 +350 -0.0449914 0.0768094 0.0302276 +351 -0.0408502 0.06658 0.00836849 +352 -0.0199988 -0.0118916 0.004906 +353 0.00337131 0.0455887 0.0238561 +354 0.00477413 -0.0721541 0.0211645 +355 -0.00344193 -0.049333 0.032475 +356 0.0427245 -0.0268877 0.00738607 +357 0.0272704 -0.0238375 0.00669928 +358 -0.00610544 -0.0476638 0.0181008 +359 -0.00760153 0.0503529 0.00747858 +360 0.0131109 -0.0422224 0.0405109 +361 0.00214561 -0.0490294 0.0151357 +362 -0.0598224 0.0805424 0.0511855 +363 -0.0204542 0.0588165 0.013102 +364 0.059357 -0.0190886 0.00813027 +365 -0.00100716 0.0422264 0.0325724 +366 0.0325535 -0.0244764 0.012522 +367 -0.000431427 -0.0574818 0.0137747 +368 0.0114251 0.0275734 0.00440942 +369 0.00337666 -0.0559724 0.0148659 +370 -0.0262911 0.0586227 0.0207785 +371 -0.0699467 0.0813567 0.0499003 +372 0.0494602 -0.0133111 0.00757754 +373 0.00758285 0.0333008 0.0104911 +374 0.00657287 0.032122 0.00603963 +375 0.000332803 -0.0511328 0.0180756 +376 -0.021764 0.0620607 0.0118108 +377 -0.0454672 0.075167 0.035911 +378 0.00139884 0.045926 0.0128133 +379 0.0176314 0.0311493 0.00370344 +380 -0.0159418 -0.0158578 0.00793814 +381 -0.0229387 0.0691641 0.0166572 +382 -0.00133409 -0.0449329 0.0187829 +383 -0.0538019 0.0611146 0.00198764 +384 0.0305208 -0.00256491 0.0101919 +385 0.0623596 -0.00697151 0.00683979 +386 0.0236819 -0.00777996 0.0526871 +387 0.0118138 -0.0144241 0.0430193 +388 0.0137156 -0.00365078 0.00732253 +389 -0.0257884 0.0686739 0.0150694 +390 -0.0530331 0.060812 0.00248197 +391 -0.000421194 -0.0523335 0.00879177 +392 0.0193846 -0.00072024 0.0649221 +393 0.00485856 0.0133946 0.0114741 +394 -0.0053823 -0.0743714 0.0141262 +395 0.016958 0.0166471 0.00740593 +396 0.0429338 -0.0266961 0.0110582 +397 -0.0650475 0.05473 0.00191127 +398 0.00924818 0.0356698 0.00715588 +399 -0.042468 0.0652669 0.00790867 +400 0.00699205 0.0348997 0.00576165 +401 -0.012123 0.00171435 0.00688121 +402 0.017741 0.00126373 0.0717161 +403 -0.00477874 -0.0228765 0.0123522 +404 -0.05496 0.0793832 0.0329037 +405 -0.0253736 -0.000654191 0.00342534 +406 0.0220159 -0.0128389 0.0555838 +407 0.0187915 0.00366305 0.0653901 +408 -0.0635923 0.0794618 0.0351284 +409 0.0187293 0.00901455 0.0689246 +410 -0.0507436 0.0790633 0.0364811 +411 0.00440962 0.0291856 0.00589534 +412 -0.0610541 0.0815764 0.0467801 +413 -0.0264169 0.0641898 0.0180225 +414 0.0590681 -0.0129818 0.00969293 +415 0.0316732 -0.013669 0.00892731 +416 -0.0368828 0.0732351 0.028231 +417 0.0147007 -0.0293577 0.0425282 +418 -0.00226105 0.042112 0.00818422 +419 -0.022404 0.068624 0.0211714 +420 0.018834 0.0296379 0.0101126 +421 0.0545664 -0.023882 0.00596013 +422 -0.0610274 0.0626039 0.00623226 +423 0.0209345 -0.0123916 0.0558755 +424 -0.064258 0.0639612 0.00701622 +425 -0.0530259 0.0709966 0.0104874 +426 -0.000350232 0.0328643 0.00950357 +427 0.0179821 0.0260225 0.00525665 +428 -0.071629 0.0809096 0.0500374 +429 0.0431333 -0.00662611 0.0109755 +430 -0.0367738 0.072104 0.0272887 +431 -0.00147996 0.0424733 0.00778004 +432 -0.0489442 0.0792518 0.0424775 +433 0.0178184 0.00830923 0.0698262 +434 -0.00256208 -0.0518644 0.0119693 +435 -0.0024457 0.0347988 0.0115191 +436 -0.0226391 0.067054 0.0236986 +437 -0.0250562 0.070839 0.0181046 +438 0.0157661 -0.010775 0.0444953 +439 -0.0587069 0.0610686 0.00549325 +440 -0.0561989 0.0607157 0.00436391 +441 0.0028322 0.0311045 0.0076099 +442 -0.061857 0.079748 0.0514834 +443 -0.0580072 0.0744854 0.0170926 +444 0.017366 0.0281829 0.00449304 +445 0.0175246 0.0303053 0.00632184 +446 -0.0583716 0.0812348 0.0494755 +447 -0.0627638 0.0811059 0.0418948 +448 0.00958337 0.0391723 0.00889538 +449 0.0164997 0.0327763 0.00400793 +450 -0.0100537 -0.019407 0.0104569 +451 0.0535082 -0.023589 0.00757618 +452 -0.0184567 0.0672393 0.0165986 +453 -0.0660887 0.0639515 0.00557639 +454 -0.0085005 0.0591911 0.0132991 +455 0.0527123 -0.00658592 0.00801901 +456 0.00664445 0.0147496 0.00979726 +457 -0.0323364 0.0646841 0.013176 +458 -0.0684981 0.0817682 0.0541475 +459 0.0424951 -0.00680449 0.0104665 +460 -0.01583 0.0638299 0.0140017 +461 -0.0408586 0.0747808 0.0276312 +462 -0.0213675 0.00505684 0.00440033 +463 -0.0609542 0.0784149 0.029815 +464 0.0458286 -0.0196104 0.0115924 +465 0.0619857 -0.0044448 0.00717137 +466 -0.0549453 0.0736446 0.0144159 +467 -0.0660739 0.0797747 0.0511232 +468 -0.0150243 -0.0138696 0.00597473 +469 -0.0208919 0.0664273 0.014553 +470 -0.0583912 0.0766731 0.0277458 +471 -0.00499489 -0.0492059 0.0154875 +472 -0.0177596 -0.0149926 0.00640227 +473 -0.0656257 0.0638276 0.00437301 +474 -0.00111824 -0.0505712 0.010634 +475 -0.0234714 0.0595273 0.0150887 +476 -0.0117477 -0.00786715 0.0107629 +477 -0.0329423 0.0662408 0.012525 +478 -0.0588644 0.0778049 0.0265316 +479 -0.038272 0.0710121 0.0277124 +480 0.0147178 0.0228905 0.00513556 +481 -0.00242697 -0.0228032 0.0106496 +482 -0.00998317 -0.0196685 0.00798312 +483 0.00194711 0.0338412 0.00734265 +484 -0.0101071 0.0571173 0.0108272 +485 -0.000192036 0.0305177 0.010316 +486 -0.0662236 0.0609953 0.00234663 +487 -0.0383437 0.071981 0.0290737 +488 0.0464353 -0.0271448 0.00729223 +489 -0.0113654 0.0558876 0.00985606 +490 -0.0600686 0.0581853 0.00037707 +491 0.0184892 0.00651809 0.072001 +492 -0.0272353 0.0661385 0.0125002 +493 0.0386787 -0.00939756 0.0110365 +494 -0.00702298 -0.0554164 0.0301677 +495 -0.0387296 0.0725599 0.0291973 +496 -0.0195884 -0.00971304 0.00731553 +497 0.000980398 0.0340005 0.00831153 +498 -0.00251349 -0.0493306 0.0137872 +499 -0.0208118 0.00468072 0.00662791 +500 0.0145465 0.0247675 0.00685396 +501 0.0539643 -0.00601143 0.00911787 +502 0.0615879 -0.00432066 0.00875869 +503 -0.0649217 0.0800024 0.0383643 +504 0.00460493 0.00849738 0.0127005 +505 -0.0606311 0.0803611 0.0379233 +506 -0.00316884 0.0400824 0.00969248 +507 -0.0308482 0.067467 0.0126012 +508 0.0120049 0.00511369 0.00824306 +509 0.0117314 0.0134932 0.00784586 +510 0.0067401 0.0222359 0.00786688 +511 0.000365941 0.0444987 0.0334101 +512 0.00589042 0.0427357 0.0325284 +513 0.0134556 0.013691 0.0071386 +514 0.0155774 0.00572549 0.00675779 +515 -0.0442054 0.0654197 0.00607699 +516 0.00863004 0.0184766 0.00878081 +517 -0.0111016 -0.0170398 0.0107756 +518 -0.0162643 0.06208 0.0123266 +519 -0.0670643 0.0628756 0.0047451 +520 -0.0673064 0.0791769 0.0489333 +521 -0.0566743 0.0588231 0.00264455 +522 -0.0713841 0.080001 0.0523997 +523 -0.0690781 0.0794039 0.0521145 +524 -0.0589744 0.0702988 0.0123753 +525 -0.0108026 0.05228 0.00636676 +526 -0.0113486 0.0541547 0.00728553 +527 -0.0299136 0.0686241 0.0165753 +528 0.0505332 -0.0225927 0.00635398 +529 0.0180077 0.0031318 0.0704387 +530 -0.0235313 0.0640143 0.012641 +531 -0.0235569 0.00584404 0.00381922 +532 0.0384718 -0.0113423 0.0144484 +533 0.0182407 0.00232532 0.0728388 +534 -0.0235752 0.00407866 0.00373027 +535 -0.011585 0.0522432 0.00647843 +536 0.0400312 -0.00904366 0.0126741 +537 -0.0178591 -0.000359808 0.00797485 +538 -0.067167 0.0625514 0.00392853 +539 -0.0596438 0.0779391 0.0290601 +540 0.0013543 0.0302152 0.00901705 +541 0.0168301 0.00522322 0.0737244 +542 0.0174324 0.00448014 0.0738384 +543 -0.0618546 0.0649931 0.00590465 +544 0.0194429 0.0304209 0.00452872 +545 -0.0236633 0.0648084 0.0124456 +546 -0.00249493 -0.0562542 0.012985 +547 -0.0025263 -0.0246783 0.0125409 +548 -0.0396392 0.0718092 0.02876 +549 -0.0158083 -0.0164708 0.00645267 +550 0.016879 0.0245859 0.0055459 +551 -0.0688499 0.0811361 0.0461884 +552 0.0290982 -0.00647478 0.00827907 +553 -0.041817 0.0761358 0.0343691 +554 -0.0642688 0.0653922 0.00517065 +555 -0.0162175 0.00239503 0.00694561 +556 0.00467524 0.0360758 0.00643588 +557 -0.0222973 0.0035638 0.00646752 +558 -0.0708092 0.0801688 0.0482801 +559 -0.0549524 0.0787083 0.0296023 +560 -0.0631054 0.0672415 0.00811831 +561 -0.0155444 -0.0163359 0.0060847 +562 -0.0574097 0.0788047 0.0473507 +563 -0.0558952 0.0591814 0.001764 +564 -0.0177409 0.0619627 0.0144786 +565 -0.00178349 -0.0487397 0.0125937 +566 -0.0111058 0.0522074 0.00829904 +567 -0.0260139 0.00360897 0.00461987 +568 -0.0204566 0.00423454 0.00564674 +569 0.00612936 0.0370467 0.00680554 +570 0.010446 0.0313554 0.00705031 +571 -0.0569353 0.05965 0.00118235 +572 -0.0506685 0.0625792 0.00279292 +573 -0.0249761 0.00485573 0.00443819 +574 0.0172421 0.00725128 0.0738262 +575 -0.0219613 0.0643004 0.0138184 +576 -0.00260185 -0.0513557 0.0142694 +577 -0.0167422 0.00259292 0.00779623 +578 0.00214524 0.0341103 0.00650831 +579 -0.0236765 0.00572293 0.004305 +580 -0.0616879 0.0784644 0.0353636 +581 -0.0125522 0.0533024 0.00573952 +582 -0.00373263 -0.048886 0.014509 +583 -0.00253347 -0.0472982 0.0131992 +584 -0.0128746 -0.017623 0.00940414 +585 -5.43548e-05 0.0393803 0.00728201 +586 -0.0258702 0.00405717 0.00525282 +587 0.0183599 0.0265636 0.00640112 +588 0.0459896 -0.0257989 0.0100883 +589 -0.0295424 0.0680594 0.0247957 +590 -0.0245383 0.0634107 0.0123732 +591 0.0066096 0.0377811 0.00691952 +592 -0.0450015 0.0646553 0.00575343 +593 -0.0622505 0.0661482 0.00839783 +594 -0.0256248 0.0608105 0.0161665 +595 0.017488 0.00853314 0.0720965 +596 -0.0596734 0.0705097 0.00992485 +597 -0.0665798 0.0628689 0.00493615 +598 -0.0624322 0.0664941 0.0080812 +599 0.0436037 -0.00911409 0.00950451 +600 -0.0258241 0.00183578 0.00455937 +601 -0.0702703 0.0796913 0.0546337 +602 -0.027947 0.0630495 0.0231884 +603 -0.0601839 0.0704633 0.0106076 +604 -0.019796 -0.0130118 0.0069497 +605 -0.0183149 0.0630548 0.012418 +606 -0.0302535 0.0701272 0.02364 +607 -0.0574291 0.0790851 0.0314511 +608 -0.0506885 0.0650762 0.00396145 +609 -0.021101 0.0616869 0.0137094 +610 -0.0331684 0.0670427 0.023997 +611 0.0134393 0.00644533 0.00718965 +612 -0.0111807 -0.0194906 0.00818236 +613 -0.0255718 0.00304117 0.00332801 +614 -0.0126697 -0.015488 0.00653208 +615 -0.0247074 0.00660999 0.00551935 +616 0.0173416 0.0031807 0.0727906 +617 0.0172416 0.0236783 0.00588169 +618 0.0190309 0.0293428 0.00437137 +619 0.016715 0.00646681 0.0747173 +620 -0.0362286 0.072292 0.023504 +621 -0.0193589 -0.00042516 0.00470745 +622 -0.0218861 0.0643631 0.0125137 +623 -0.0102557 0.0512168 0.00711881 +624 0.0404202 -0.00631757 0.0116411 +625 0.0462272 -0.00679819 0.0101561 +626 -0.0259792 0.0656558 0.0150971 +627 0.0162732 0.0229634 0.00624384 +628 0.00353474 0.0364474 0.00843339 +629 4.6368e-06 0.0388726 0.00973083 +630 -0.0216501 0.0633078 0.012475 +631 -0.0653553 0.0635995 0.0060088 +632 -0.0129397 0.0533345 0.00604151 +633 -0.00189413 -0.0244631 0.013557 +634 -0.0610974 0.0673557 0.00916116 +635 0.0169636 0.00823874 0.0726305 +636 -0.0262169 0.00566462 0.00486021 +637 -0.00105663 -0.050339 0.013034 +638 -0.0522352 0.0618469 0.00239028 +639 -0.0658611 0.0623674 0.00600767 +640 -0.0308719 0.0671807 0.0240148 +641 -0.0271033 0.0631674 0.0232081 +642 0.000463176 0.0377435 0.00713404 +643 0.0197653 -0.0105149 0.0573133 +644 -0.0261272 0.00574879 0.00514751 +645 -0.0256133 0.00236555 0.00535812 +646 0.0395658 -0.00664927 0.0115095 +647 -0.0346515 0.0704144 0.0260764 +648 -0.0676857 0.0619198 0.00410476 +649 -0.0352382 0.0722683 0.0261851 +650 -0.0489272 0.0632235 0.00329626 +651 -0.0514659 0.0617489 0.00295197 +652 -0.070483 0.0805389 0.0464472 +$EndNodes +$Elements +1654 +1 4 0 26 15 543 25 +2 4 0 227 308 190 188 +3 4 0 203 353 199 163 +4 4 0 331 305 504 150 +5 4 0 142 328 128 138 +6 4 0 490 439 18 571 +7 4 0 364 289 287 414 +8 4 0 296 336 304 298 +9 4 0 564 419 300 381 +10 4 0 398 569 373 591 +11 4 0 486 473 639 422 +12 4 0 338 89 566 489 +13 4 0 332 554 543 424 +14 4 0 80 67 71 302 +15 4 0 149 146 109 108 +16 4 0 98 90 375 342 +17 4 0 341 308 325 313 +18 4 0 147 314 126 116 +19 4 0 124 318 156 131 +20 4 0 245 322 206 308 +21 4 0 348 311 516 186 +22 4 0 135 150 319 151 +23 4 0 147 314 307 311 +24 4 0 464 588 301 528 +25 4 0 461 33 35 333 +26 4 0 196 192 373 314 +27 4 0 108 81 302 122 +28 4 0 366 258 227 357 +29 4 0 511 107 512 353 +30 4 0 146 170 354 172 +31 4 0 297 175 156 130 +32 4 0 130 297 175 308 +33 4 0 318 159 319 195 +34 4 0 154 123 122 342 +35 4 0 261 308 259 260 +36 4 0 132 142 128 318 +37 4 0 241 250 240 205 +38 4 0 226 227 248 324 +39 4 0 575 609 475 49 +40 4 0 375 91 123 90 +41 4 0 260 308 255 251 +42 4 0 517 612 63 482 +43 4 0 120 117 131 297 +44 4 0 318 131 297 156 +45 4 0 147 319 311 307 +46 4 0 131 120 297 130 +47 4 0 120 297 111 117 +48 4 0 308 174 206 360 +49 4 0 148 313 325 175 +50 4 0 148 313 175 174 +51 4 0 302 80 122 81 +52 4 0 107 353 511 110 +53 4 0 322 231 198 197 +54 4 0 61 58 564 57 +55 4 0 240 386 212 221 +56 4 0 121 297 143 117 +57 4 0 121 297 117 111 +58 4 0 307 235 314 182 +59 4 0 307 314 166 182 +60 4 0 417 308 175 316 +61 4 0 308 175 360 417 +62 4 0 601 9 458 1 +63 4 0 459 429 536 599 +64 4 0 211 242 206 308 +65 4 0 528 588 301 356 +66 4 0 316 297 308 175 +67 4 0 197 188 308 228 +68 4 0 231 308 228 197 +69 4 0 231 197 322 308 +70 4 0 188 197 308 361 +71 4 0 322 361 308 197 +72 4 0 259 308 256 255 +73 4 0 298 306 304 299 +74 4 0 302 342 146 122 +75 4 0 251 322 245 308 +76 4 0 298 306 299 236 +77 4 0 342 302 169 129 +78 4 0 157 319 331 150 +79 4 0 190 195 324 227 +80 4 0 146 342 354 154 +81 4 0 190 297 308 324 +82 4 0 236 254 306 299 +83 4 0 354 179 201 322 +84 4 0 308 297 188 361 +85 4 0 361 188 164 297 +86 4 0 195 165 190 318 +87 4 0 307 215 257 235 +88 4 0 194 235 215 307 +89 4 0 174 129 148 313 +90 4 0 169 313 129 174 +91 4 0 322 255 251 201 +92 4 0 366 265 308 258 +93 4 0 227 308 258 366 +94 4 0 258 308 249 265 +95 4 0 227 308 228 258 +96 4 0 448 192 373 196 +97 4 0 228 308 249 258 +98 4 0 296 298 514 336 +99 4 0 125 150 348 126 +100 4 0 125 160 348 150 +101 4 0 244 264 242 316 +102 4 0 264 316 244 271 +103 4 0 224 233 225 219 +104 4 0 107 353 163 199 +105 4 0 217 223 219 225 +106 4 0 308 174 313 206 +107 4 0 206 313 179 174 +108 4 0 241 230 212 233 +109 4 0 241 233 212 218 +110 4 0 267 278 312 273 +111 4 0 267 312 262 273 +112 4 0 206 179 322 245 +113 4 0 242 245 206 308 +114 4 0 144 319 159 157 +115 4 0 265 308 266 272 +116 4 0 218 219 392 233 +117 4 0 264 324 316 271 +118 4 0 324 308 264 316 +119 4 0 297 318 117 131 +120 4 0 128 117 318 124 +121 4 0 354 207 201 177 +122 4 0 207 177 354 184 +123 4 0 155 163 353 203 +124 4 0 131 297 156 130 +125 4 0 395 330 236 202 +126 4 0 164 142 318 190 +127 4 0 253 314 234 311 +128 4 0 307 314 147 166 +129 4 0 331 234 253 254 +130 4 0 306 236 298 331 +131 4 0 156 297 316 175 +132 4 0 324 319 318 316 +133 4 0 297 324 316 308 +134 4 0 373 314 102 125 +135 4 0 167 155 378 192 +136 4 0 278 324 272 269 +137 4 0 278 276 272 324 +138 4 0 319 159 157 336 +139 4 0 267 257 312 243 +140 4 0 307 215 243 257 +141 4 0 156 297 318 316 +142 4 0 207 354 170 184 +143 4 0 124 144 139 156 +144 4 0 267 312 250 243 +145 4 0 144 151 139 319 +146 4 0 318 316 319 144 +147 4 0 316 139 319 144 +148 4 0 139 144 316 156 +149 4 0 316 191 312 319 +150 4 0 316 191 317 156 +151 4 0 313 308 175 174 +152 4 0 253 234 331 311 +153 4 0 331 395 234 236 +154 4 0 272 265 308 366 +155 4 0 103 140 133 510 +156 4 0 235 199 246 314 +157 4 0 246 237 314 199 +158 4 0 144 151 319 157 +159 4 0 92 157 151 144 +160 4 0 92 159 157 144 +161 4 0 395 234 236 330 +162 4 0 395 330 202 348 +163 4 0 348 330 202 209 +164 4 0 324 312 316 271 +165 4 0 266 308 324 272 +166 4 0 324 366 308 227 +167 4 0 242 264 245 308 +168 4 0 272 266 269 324 +169 4 0 135 151 319 139 +170 4 0 40 35 28 29 +171 4 0 88 148 129 342 +172 4 0 325 342 148 88 +173 4 0 314 116 147 166 +174 4 0 77 353 320 94 +175 4 0 331 262 319 306 +176 4 0 319 317 139 316 +177 4 0 450 329 482 328 +178 4 0 183 307 147 166 +179 4 0 188 361 176 197 +180 4 0 169 179 313 174 +181 4 0 314 196 348 373 +182 4 0 102 84 116 353 +183 4 0 102 77 84 353 +184 4 0 191 147 319 317 +185 4 0 307 262 257 312 +186 4 0 307 257 246 235 +187 4 0 307 257 262 246 +188 4 0 128 318 144 124 +189 4 0 246 314 237 253 +190 4 0 314 203 237 234 +191 4 0 142 128 318 138 +192 4 0 253 237 234 314 +193 4 0 306 319 331 336 +194 4 0 307 314 235 246 +195 4 0 316 250 312 191 +196 4 0 450 403 349 329 +197 4 0 121 297 101 143 +198 4 0 382 164 101 297 +199 4 0 369 198 322 193 +200 4 0 264 266 324 269 +201 4 0 322 354 170 207 +202 4 0 322 170 193 207 +203 4 0 353 84 116 110 +204 4 0 70 302 68 83 +205 4 0 331 311 234 395 +206 4 0 323 493 282 301 +207 4 0 269 278 324 271 +208 4 0 278 312 324 271 +209 4 0 207 170 180 184 +210 4 0 207 170 193 180 +211 4 0 325 130 175 308 +212 4 0 146 354 170 154 +213 4 0 354 302 342 146 +214 4 0 161 348 510 181 +215 4 0 182 314 199 235 +216 4 0 322 354 369 170 +217 4 0 231 207 322 198 +218 4 0 313 322 375 341 +219 4 0 375 361 341 322 +220 4 0 322 207 193 198 +221 4 0 297 143 164 101 +222 4 0 221 213 240 232 +223 4 0 190 188 308 297 +224 4 0 341 361 375 382 +225 4 0 341 308 313 322 +226 4 0 134 158 184 354 +227 4 0 247 308 261 249 +228 4 0 263 308 260 251 +229 4 0 318 319 159 144 +230 4 0 309 262 306 319 +231 4 0 250 204 243 312 +232 4 0 448 192 167 378 +233 4 0 37 333 620 35 +234 4 0 37 33 333 35 +235 4 0 297 318 316 324 +236 4 0 167 448 378 153 +237 4 0 212 218 233 219 +238 4 0 88 325 342 494 +239 4 0 246 307 314 253 +240 4 0 307 253 246 262 +241 4 0 126 311 150 348 +242 4 0 388 611 336 514 +243 4 0 348 234 420 314 +244 4 0 236 254 331 306 +245 4 0 348 314 311 234 +246 4 0 211 308 360 417 +247 4 0 373 102 320 125 +248 4 0 316 250 191 438 +249 4 0 250 205 191 438 +250 4 0 254 262 306 309 +251 4 0 254 309 306 310 +252 4 0 299 254 306 310 +253 4 0 331 262 306 254 +254 4 0 292 294 295 293 +255 4 0 194 307 215 204 +256 4 0 304 306 384 299 +257 4 0 267 312 257 262 +258 4 0 353 192 378 155 +259 4 0 319 159 336 195 +260 4 0 353 192 373 378 +261 4 0 336 185 388 195 +262 4 0 312 250 271 267 +263 4 0 271 250 312 316 +264 4 0 261 249 308 265 +265 4 0 268 308 265 261 +266 4 0 247 308 249 228 +267 4 0 227 195 324 226 +268 4 0 366 324 415 337 +269 4 0 337 366 324 357 +270 4 0 190 195 318 324 +271 4 0 156 318 124 144 +272 4 0 263 266 308 264 +273 4 0 251 263 308 264 +274 4 0 197 198 322 369 +275 4 0 154 354 369 342 +276 4 0 188 308 228 227 +277 4 0 79 328 138 92 +278 4 0 316 317 139 156 +279 4 0 360 175 308 174 +280 4 0 255 251 308 322 +281 4 0 255 256 252 308 +282 4 0 247 228 231 308 +283 4 0 247 308 231 256 +284 4 0 134 149 394 354 +285 4 0 83 162 96 302 +286 4 0 161 373 140 348 +287 4 0 88 67 302 68 +288 4 0 302 97 88 68 +289 4 0 512 166 314 182 +290 4 0 420 192 314 234 +291 4 0 348 330 420 234 +292 4 0 192 314 234 203 +293 4 0 91 123 105 115 +294 4 0 394 70 302 81 +295 4 0 309 273 262 319 +296 4 0 319 262 312 273 +297 4 0 67 302 68 70 +298 4 0 271 278 312 267 +299 4 0 66 57 326 58 +300 4 0 188 136 176 361 +301 4 0 157 331 185 504 +302 4 0 136 361 188 164 +303 4 0 244 250 271 316 +304 4 0 71 302 67 70 +305 4 0 244 213 232 240 +306 4 0 81 302 71 70 +307 4 0 354 149 108 146 +308 4 0 314 237 203 199 +309 4 0 506 378 435 629 +310 4 0 244 438 316 213 +311 4 0 97 302 169 162 +312 4 0 244 316 438 250 +313 4 0 313 129 342 169 +314 4 0 382 113 101 164 +315 4 0 506 435 378 94 +316 4 0 91 123 85 105 +317 4 0 308 264 245 251 +318 4 0 242 264 308 316 +319 4 0 450 349 482 329 +320 4 0 314 373 348 125 +321 4 0 92 138 159 144 +322 4 0 395 311 234 348 +323 4 0 278 273 324 312 +324 4 0 373 378 435 320 +325 4 0 147 311 319 135 +326 4 0 126 311 135 150 +327 4 0 126 135 311 147 +328 4 0 314 348 311 126 +329 4 0 83 302 82 70 +330 4 0 378 435 629 373 +331 4 0 195 159 165 318 +332 4 0 316 312 324 319 +333 4 0 156 175 316 387 +334 4 0 336 298 514 331 +335 4 0 88 342 129 302 +336 4 0 319 307 331 311 +337 4 0 253 314 311 307 +338 4 0 311 331 253 307 +339 4 0 297 341 308 130 +340 4 0 314 348 126 125 +341 4 0 147 314 311 126 +342 4 0 61 339 99 338 +343 4 0 250 204 312 191 +344 4 0 305 185 508 331 +345 4 0 211 242 308 316 +346 4 0 211 308 417 316 +347 4 0 213 316 211 417 +348 4 0 214 215 230 204 +349 4 0 244 316 242 211 +350 4 0 244 211 213 316 +351 4 0 465 501 344 502 +352 4 0 108 354 302 394 +353 4 0 313 129 148 342 +354 4 0 337 324 415 248 +355 4 0 337 258 366 357 +356 4 0 121 101 297 111 +357 4 0 382 101 111 297 +358 4 0 157 159 185 336 +359 4 0 226 336 195 324 +360 4 0 307 262 331 253 +361 4 0 307 262 319 331 +362 4 0 331 254 253 262 +363 4 0 248 336 552 296 +364 4 0 319 324 195 336 +365 4 0 248 296 226 336 +366 4 0 324 248 336 552 +367 4 0 147 183 191 307 +368 4 0 282 281 276 323 +369 4 0 281 323 282 301 +370 4 0 109 119 105 122 +371 4 0 297 143 117 318 +372 4 0 109 122 105 80 +373 4 0 308 366 324 272 +374 4 0 297 318 324 190 +375 4 0 297 190 164 318 +376 4 0 214 204 230 212 +377 4 0 224 212 214 230 +378 4 0 297 143 318 164 +379 4 0 264 308 324 266 +380 4 0 264 269 324 271 +381 4 0 132 117 143 318 +382 4 0 130 297 341 120 +383 4 0 341 130 120 98 +384 4 0 277 343 356 279 +385 4 0 325 308 175 313 +386 4 0 109 81 108 122 +387 4 0 109 122 108 146 +388 4 0 348 234 395 330 +389 4 0 341 111 120 297 +390 4 0 341 100 98 120 +391 4 0 341 111 100 120 +392 4 0 226 336 324 248 +393 4 0 318 319 324 195 +394 4 0 275 270 324 309 +395 4 0 309 336 324 319 +396 4 0 552 270 336 324 +397 4 0 273 309 275 324 +398 4 0 403 328 329 450 +399 4 0 382 111 341 297 +400 4 0 361 322 308 341 +401 4 0 361 341 308 297 +402 4 0 342 85 73 90 +403 4 0 342 73 85 80 +404 4 0 323 324 366 276 +405 4 0 361 297 164 382 +406 4 0 96 82 83 302 +407 4 0 45 647 44 42 +408 4 0 179 354 201 177 +409 4 0 53 621 54 347 +410 4 0 117 124 131 318 +411 4 0 156 144 316 318 +412 4 0 369 198 193 141 +413 4 0 342 302 88 67 +414 4 0 67 80 342 302 +415 4 0 73 80 342 67 +416 4 0 342 73 67 76 +417 4 0 372 528 289 285 +418 4 0 285 528 289 287 +419 4 0 355 98 325 494 +420 4 0 122 119 105 123 +421 4 0 394 82 134 302 +422 4 0 494 88 76 342 +423 4 0 109 81 122 80 +424 4 0 447 580 503 505 +425 4 0 114 118 141 145 +426 4 0 311 150 319 135 +427 4 0 108 122 302 146 +428 4 0 204 307 183 194 +429 4 0 191 204 307 183 +430 4 0 382 101 100 111 +431 4 0 382 111 100 341 +432 4 0 318 159 138 144 +433 4 0 588 281 301 356 +434 4 0 87 61 77 57 +435 4 0 318 159 165 138 +436 4 0 7 12 2 486 +437 4 0 316 191 319 317 +438 4 0 208 196 449 445 +439 4 0 322 369 354 313 +440 4 0 354 158 177 162 +441 4 0 354 169 162 179 +442 4 0 313 369 354 342 +443 4 0 179 162 354 177 +444 4 0 130 98 341 355 +445 4 0 325 130 341 355 +446 4 0 337 357 324 248 +447 4 0 324 357 227 248 +448 4 0 588 281 464 301 +449 4 0 375 341 382 98 +450 4 0 454 75 61 155 +451 4 0 353 77 84 74 +452 4 0 331 305 185 504 +453 4 0 311 331 319 150 +454 4 0 378 339 167 106 +455 4 0 318 190 142 165 +456 4 0 138 142 165 318 +457 4 0 18 12 397 14 +458 4 0 298 514 331 513 +459 4 0 118 137 141 168 +460 4 0 298 331 236 395 +461 4 0 395 298 331 513 +462 4 0 93 157 92 159 +463 4 0 354 158 184 177 +464 4 0 151 157 92 93 +465 4 0 78 93 151 92 +466 4 0 378 448 629 153 +467 4 0 102 314 126 125 +468 4 0 126 116 314 102 +469 4 0 61 72 303 75 +470 4 0 39 461 350 553 +471 4 0 350 39 33 461 +472 4 0 311 331 513 395 +473 4 0 311 331 305 509 +474 4 0 353 102 314 116 +475 4 0 204 215 243 307 +476 4 0 106 153 167 378 +477 4 0 97 162 83 302 +478 4 0 107 353 199 512 +479 4 0 297 188 164 190 +480 4 0 147 319 139 135 +481 4 0 77 353 87 74 +482 4 0 353 203 199 314 +483 4 0 512 314 353 199 +484 4 0 37 38 29 35 +485 4 0 485 140 373 125 +486 4 0 398 448 373 196 +487 4 0 196 570 373 398 +488 4 0 324 248 552 415 +489 4 0 415 270 552 324 +490 4 0 52 57 594 564 +491 4 0 285 289 414 287 +492 4 0 438 250 205 240 +493 4 0 524 425 25 17 +494 4 0 29 25 524 425 +495 4 0 87 77 61 353 +496 4 0 93 92 138 159 +497 4 0 93 92 79 138 +498 4 0 203 192 353 155 +499 4 0 192 353 314 203 +500 4 0 88 302 129 97 +501 4 0 169 342 354 302 +502 4 0 147 319 317 139 +503 4 0 435 426 629 373 +504 4 0 197 168 369 176 +505 4 0 369 176 361 197 +506 4 0 157 151 319 150 +507 4 0 307 319 312 191 +508 4 0 312 307 191 204 +509 4 0 628 373 441 374 +510 4 0 513 331 311 509 +511 4 0 49 594 413 46 +512 4 0 303 163 87 61 +513 4 0 146 342 154 122 +514 4 0 274 366 415 337 +515 4 0 274 258 366 337 +516 4 0 87 57 74 66 +517 4 0 304 306 336 384 +518 4 0 204 250 205 191 +519 4 0 110 74 66 87 +520 4 0 163 87 61 353 +521 4 0 204 205 250 241 +522 4 0 387 438 213 316 +523 4 0 150 160 348 311 +524 4 0 313 369 342 375 +525 4 0 313 322 369 375 +526 4 0 97 129 169 302 +527 4 0 504 305 393 150 +528 4 0 181 348 500 187 +529 4 0 610 527 42 44 +530 4 0 44 527 42 620 +531 4 0 311 305 456 509 +532 4 0 311 509 456 516 +533 4 0 365 512 166 116 +534 4 0 116 512 166 314 +535 4 0 509 305 508 331 +536 4 0 322 369 193 170 +537 4 0 535 526 581 632 +538 4 0 182 314 512 199 +539 4 0 497 441 373 540 +540 4 0 37 42 46 527 +541 4 0 500 209 187 348 +542 4 0 312 257 307 243 +543 4 0 323 366 281 276 +544 4 0 348 420 209 196 +545 4 0 366 279 276 272 +546 4 0 202 500 186 348 +547 4 0 386 406 221 232 +548 4 0 64 526 62 489 +549 4 0 336 159 185 195 +550 4 0 404 24 559 335 +551 4 0 404 24 607 559 +552 4 0 384 336 552 270 +553 4 0 244 240 438 213 +554 4 0 244 438 240 250 +555 4 0 430 461 620 333 +556 4 0 461 333 35 620 +557 4 0 61 564 64 334 +558 4 0 381 437 47 413 +559 4 0 279 277 265 258 +560 4 0 279 277 258 274 +561 4 0 186 500 181 348 +562 4 0 140 510 348 160 +563 4 0 377 410 36 350 +564 4 0 202 330 236 209 +565 4 0 380 345 614 468 +566 4 0 99 339 378 106 +567 4 0 378 106 418 99 +568 4 0 378 448 373 629 +569 4 0 194 235 307 182 +570 4 0 194 307 166 182 +571 4 0 194 307 183 166 +572 4 0 353 373 320 378 +573 4 0 68 97 83 302 +574 4 0 347 496 604 476 +575 4 0 161 181 411 373 +576 4 0 570 374 400 368 +577 4 0 40 38 35 29 +578 4 0 364 289 327 528 +579 4 0 324 309 319 273 +580 4 0 353 378 320 94 +581 4 0 358 91 471 375 +582 4 0 134 394 302 354 +583 4 0 394 149 108 354 +584 4 0 172 354 146 149 +585 4 0 382 358 471 375 +586 4 0 101 382 90 358 +587 4 0 651 346 638 390 +588 4 0 382 90 100 101 +589 4 0 334 594 564 475 +590 4 0 369 361 375 322 +591 4 0 322 197 369 361 +592 4 0 342 325 98 494 +593 4 0 325 313 148 342 +594 4 0 342 325 375 98 +595 4 0 115 369 123 367 +596 4 0 342 98 76 494 +597 4 0 369 375 576 115 +598 4 0 353 512 116 314 +599 4 0 336 304 552 296 +600 4 0 336 306 304 298 +601 4 0 226 514 336 296 +602 4 0 108 302 81 394 +603 4 0 181 411 373 374 +604 4 0 26 440 571 383 +605 4 0 26 383 346 440 +606 4 0 211 360 308 206 +607 4 0 87 74 57 77 +608 4 0 358 113 101 382 +609 4 0 195 388 336 226 +610 4 0 241 233 218 238 +611 4 0 155 339 378 353 +612 4 0 345 79 468 476 +613 4 0 213 316 417 175 +614 4 0 387 316 213 175 +615 4 0 312 307 262 319 +616 4 0 435 485 426 373 +617 4 0 435 373 125 485 +618 4 0 299 310 306 384 +619 4 0 26 425 25 34 +620 4 0 118 114 367 434 +621 4 0 26 34 25 608 +622 4 0 223 222 529 392 +623 4 0 527 38 37 35 +624 4 0 37 527 46 38 +625 4 0 342 123 90 375 +626 4 0 342 123 85 90 +627 4 0 335 350 33 35 +628 4 0 350 461 33 35 +629 4 0 85 91 90 123 +630 4 0 259 247 308 261 +631 4 0 629 628 448 373 +632 4 0 633 142 328 128 +633 4 0 629 497 628 373 +634 4 0 303 61 87 72 +635 4 0 236 254 234 331 +636 4 0 341 98 325 355 +637 4 0 373 570 400 569 +638 4 0 398 570 373 569 +639 4 0 49 413 527 46 +640 4 0 49 46 527 457 +641 4 0 49 626 48 527 +642 4 0 241 204 243 250 +643 4 0 49 527 48 457 +644 4 0 392 218 233 238 +645 4 0 233 392 238 223 +646 4 0 178 198 197 141 +647 4 0 198 197 141 369 +648 4 0 364 290 287 528 +649 4 0 419 381 564 413 +650 4 0 92 78 79 59 +651 4 0 192 373 314 353 +652 4 0 386 406 238 423 +653 4 0 367 369 137 391 +654 4 0 437 413 419 606 +655 4 0 413 437 47 606 +656 4 0 239 252 322 255 +657 4 0 454 61 339 155 +658 4 0 34 466 425 29 +659 4 0 221 386 232 240 +660 4 0 60 64 489 484 +661 4 0 484 65 60 64 +662 4 0 212 386 218 221 +663 4 0 241 240 386 212 +664 4 0 241 205 240 212 +665 4 0 607 24 16 470 +666 4 0 620 42 37 527 +667 4 0 37 333 42 620 +668 4 0 95 87 66 69 +669 4 0 113 164 382 361 +670 4 0 410 30 432 21 +671 4 0 371 1 522 458 +672 4 0 527 47 43 40 +673 4 0 596 425 17 15 +674 4 0 393 456 160 311 +675 4 0 110 95 87 66 +676 4 0 160 311 456 516 +677 4 0 512 511 365 166 +678 4 0 353 511 365 512 +679 4 0 128 144 318 138 +680 4 0 341 130 325 308 +681 4 0 87 61 57 58 +682 4 0 419 58 564 72 +683 4 0 414 289 327 364 +684 4 0 320 378 435 94 +685 4 0 364 528 287 289 +686 4 0 212 221 205 240 +687 4 0 134 172 149 354 +688 4 0 134 172 354 184 +689 4 0 319 147 191 307 +690 4 0 589 641 606 436 +691 4 0 347 79 59 476 +692 4 0 345 79 476 92 +693 4 0 92 138 144 328 +694 4 0 86 92 144 328 +695 4 0 32 399 34 38 +696 4 0 306 309 336 310 +697 4 0 347 604 468 476 +698 4 0 347 468 79 476 +699 4 0 614 345 79 468 +700 4 0 384 310 336 270 +701 4 0 439 25 26 422 +702 4 0 196 192 314 420 +703 4 0 348 420 196 314 +704 4 0 132 143 142 318 +705 4 0 164 142 143 318 +706 4 0 386 406 423 221 +707 4 0 35 527 38 40 +708 4 0 158 354 96 162 +709 4 0 169 302 354 162 +710 4 0 334 475 564 363 +711 4 0 155 61 303 75 +712 4 0 94 353 378 339 +713 4 0 224 233 219 212 +714 4 0 214 215 204 194 +715 4 0 204 243 230 241 +716 4 0 204 230 212 241 +717 4 0 391 474 369 136 +718 4 0 286 588 528 356 +719 4 0 35 620 527 47 +720 4 0 136 474 361 565 +721 4 0 566 526 632 64 +722 4 0 490 439 11 14 +723 4 0 209 330 420 348 +724 4 0 35 527 40 47 +725 4 0 76 342 73 98 +726 4 0 77 353 102 320 +727 4 0 268 308 261 260 +728 4 0 167 155 339 378 +729 4 0 465 289 385 344 +730 4 0 255 308 260 259 +731 4 0 335 24 470 33 +732 4 0 559 24 470 335 +733 4 0 522 1 371 428 +734 4 0 347 53 496 54 +735 4 0 559 24 607 470 +736 4 0 476 347 496 54 +737 4 0 312 204 243 307 +738 4 0 230 215 243 204 +739 4 0 241 218 212 386 +740 4 0 241 238 218 386 +741 4 0 29 33 28 23 +742 4 0 23 335 559 470 +743 4 0 297 382 361 341 +744 4 0 336 611 185 331 +745 4 0 388 185 336 611 +746 4 0 353 373 102 320 +747 4 0 373 102 314 353 +748 4 0 44 527 606 610 +749 4 0 74 110 84 353 +750 4 0 610 527 606 413 +751 4 0 325 341 375 98 +752 4 0 369 136 137 391 +753 4 0 169 354 342 313 +754 4 0 274 366 279 281 +755 4 0 281 366 279 276 +756 4 0 322 313 206 308 +757 4 0 414 289 344 385 +758 4 0 114 546 367 434 +759 4 0 367 391 434 369 +760 4 0 155 163 303 61 +761 4 0 47 620 527 44 +762 4 0 384 304 552 336 +763 4 0 384 310 306 336 +764 4 0 99 378 339 94 +765 4 0 506 94 378 99 +766 4 0 365 353 512 116 +767 4 0 378 99 418 506 +768 4 0 478 23 559 470 +769 4 0 328 86 633 128 +770 4 0 265 308 268 266 +771 4 0 268 308 263 266 +772 4 0 564 419 436 58 +773 4 0 460 75 564 65 +774 4 0 339 61 99 94 +775 4 0 518 564 65 460 +776 4 0 643 216 229 392 +777 4 0 342 88 76 67 +778 4 0 26 422 11 439 +779 4 0 26 440 439 571 +780 4 0 411 161 373 441 +781 4 0 442 467 412 10 +782 4 0 350 377 24 33 +783 4 0 225 409 217 223 +784 4 0 410 377 24 350 +785 4 0 24 350 33 335 +786 4 0 371 522 523 458 +787 4 0 278 324 273 276 +788 4 0 273 324 275 276 +789 4 0 170 354 172 184 +790 4 0 169 179 354 313 +791 4 0 607 16 24 580 +792 4 0 367 391 137 118 +793 4 0 35 620 37 527 +794 4 0 548 33 461 333 +795 4 0 414 385 344 294 +796 4 0 414 289 288 344 +797 4 0 65 64 484 454 +798 4 0 93 79 78 401 +799 4 0 375 382 358 90 +800 4 0 413 575 564 594 +801 4 0 187 181 368 189 +802 4 0 358 375 90 91 +803 4 0 275 276 324 323 +804 4 0 493 270 323 275 +805 4 0 532 323 276 275 +806 4 0 324 270 323 415 +807 4 0 275 323 324 270 +808 4 0 157 331 319 336 +809 4 0 454 339 61 338 +810 4 0 527 47 507 43 +811 4 0 74 87 110 353 +812 4 0 61 353 339 155 +813 4 0 444 445 618 379 +814 4 0 173 133 160 510 +815 4 0 352 604 468 347 +816 4 0 161 181 373 348 +817 4 0 23 335 470 33 +818 4 0 181 187 374 373 +819 4 0 29 35 28 33 +820 4 0 348 187 181 373 +821 4 0 562 10 412 447 +822 4 0 10 580 503 447 +823 4 0 399 351 34 38 +824 4 0 515 592 399 32 +825 4 0 434 112 637 474 +826 4 0 134 82 96 302 +827 4 0 224 230 233 212 +828 4 0 134 302 96 354 +829 4 0 302 354 162 96 +830 4 0 376 64 60 564 +831 4 0 606 640 589 45 +832 4 0 369 137 168 141 +833 4 0 113 361 583 136 +834 4 0 197 369 168 141 +835 4 0 12 7 4 14 +836 4 0 510 181 173 171 +837 4 0 61 339 353 94 +838 4 0 369 154 170 354 +839 4 0 404 607 24 21 +840 4 0 411 374 578 441 +841 4 0 500 186 189 480 +842 4 0 535 526 632 566 +843 4 0 628 441 497 483 +844 4 0 478 23 28 559 +845 4 0 28 335 559 23 +846 4 0 93 92 78 79 +847 4 0 554 473 631 453 +848 4 0 198 178 193 141 +849 4 0 187 444 209 500 +850 4 0 226 388 336 514 +851 4 0 287 464 285 528 +852 4 0 528 301 285 372 +853 4 0 497 629 426 373 +854 4 0 394 302 70 82 +855 4 0 64 61 454 75 +856 4 0 444 587 618 445 +857 4 0 467 458 371 523 +858 4 0 371 523 520 467 +859 4 0 371 520 551 467 +860 4 0 385 465 294 292 +861 4 0 468 604 345 476 +862 4 0 584 517 63 345 +863 4 0 176 136 137 369 +864 4 0 439 440 18 571 +865 4 0 490 26 11 439 +866 4 0 324 366 227 357 +867 4 0 606 413 419 436 +868 4 0 527 48 477 507 +869 4 0 527 477 48 457 +870 4 0 527 492 48 507 +871 4 0 527 626 48 492 +872 4 0 134 354 96 158 +873 4 0 62 64 489 60 +874 4 0 52 57 370 594 +875 4 0 326 52 55 564 +876 4 0 524 425 17 19 +877 4 0 373 441 161 540 +878 4 0 373 161 140 540 +879 4 0 66 326 55 58 +880 4 0 58 326 55 564 +881 4 0 310 309 336 270 +882 4 0 324 270 336 309 +883 4 0 157 336 185 331 +884 4 0 181 411 171 161 +885 4 0 640 589 641 606 +886 4 0 537 557 621 54 +887 4 0 282 285 340 288 +888 4 0 372 285 288 340 +889 4 0 382 100 98 341 +890 4 0 502 294 465 292 +891 4 0 43 34 351 38 +892 4 0 221 240 213 205 +893 4 0 438 240 205 213 +894 4 0 425 466 524 29 +895 4 0 354 302 146 108 +896 4 0 435 426 506 629 +897 4 0 497 506 426 629 +898 4 0 187 181 374 368 +899 4 0 517 79 614 345 +900 4 0 342 90 73 98 +901 4 0 180 141 178 152 +902 4 0 178 152 141 168 +903 4 0 193 180 141 178 +904 4 0 140 161 348 510 +905 4 0 9 442 13 362 +906 4 0 442 9 13 467 +907 4 0 408 505 503 580 +908 4 0 607 580 408 16 +909 4 0 327 289 414 385 +910 4 0 372 284 283 340 +911 4 0 359 89 526 566 +912 4 0 607 539 478 470 +913 4 0 140 373 125 348 +914 4 0 328 86 92 517 +915 4 0 527 47 44 606 +916 4 0 155 163 61 353 +917 4 0 367 391 118 434 +918 4 0 338 64 61 454 +919 4 0 64 338 484 454 +920 4 0 359 89 566 338 +921 4 0 489 526 566 64 +922 4 0 448 192 378 373 +923 4 0 350 39 377 33 +924 4 0 369 137 176 168 +925 4 0 377 350 553 39 +926 4 0 325 313 375 341 +927 4 0 340 288 625 282 +928 4 0 342 313 375 325 +929 4 0 524 466 19 20 +930 4 0 425 466 19 524 +931 4 0 348 395 186 202 +932 4 0 610 44 42 45 +933 4 0 409 433 217 223 +934 4 0 217 433 529 223 +935 4 0 582 375 471 115 +936 4 0 434 474 637 369 +937 4 0 382 375 471 582 +938 4 0 98 90 382 375 +939 4 0 382 100 90 98 +940 4 0 123 105 122 85 +941 4 0 122 85 105 80 +942 4 0 43 40 34 38 +943 4 0 369 474 361 136 +944 4 0 469 452 564 460 +945 4 0 46 41 527 457 +946 4 0 415 366 274 323 +947 4 0 191 387 316 438 +948 4 0 191 387 156 316 +949 4 0 434 391 474 369 +950 4 0 502 294 344 465 +951 4 0 502 294 292 293 +952 4 0 476 59 92 79 +953 4 0 306 309 319 336 +954 4 0 528 301 464 285 +955 4 0 301 282 464 285 +956 4 0 208 449 210 379 +957 4 0 210 379 220 208 +958 4 0 551 520 10 467 +959 4 0 359 89 339 106 +960 4 0 110 353 365 116 +961 4 0 353 511 110 365 +962 4 0 118 141 145 152 +963 4 0 34 28 466 29 +964 4 0 621 347 59 54 +965 4 0 59 621 79 347 +966 4 0 342 80 122 302 +967 4 0 369 123 154 342 +968 4 0 123 85 122 342 +969 4 0 122 342 85 80 +970 4 0 450 349 612 482 +971 4 0 564 55 436 413 +972 4 0 40 38 29 34 +973 4 0 606 641 413 436 +974 4 0 28 35 335 33 +975 4 0 34 25 32 29 +976 4 0 487 548 495 479 +977 4 0 187 209 196 348 +978 4 0 461 479 430 495 +979 4 0 311 513 509 186 +980 4 0 395 311 348 186 +981 4 0 187 196 209 444 +982 4 0 485 540 426 373 +983 4 0 21 580 24 447 +984 4 0 412 447 21 562 +985 4 0 412 562 21 446 +986 4 0 447 580 24 10 +987 4 0 46 527 610 413 +988 4 0 229 392 216 222 +989 4 0 323 281 366 274 +990 4 0 281 301 274 323 +991 4 0 599 625 429 282 +992 4 0 608 25 32 34 +993 4 0 372 288 284 340 +994 4 0 227 324 190 308 +995 4 0 373 196 348 187 +996 4 0 425 25 34 29 +997 4 0 628 448 373 591 +998 4 0 591 448 373 398 +999 4 0 477 43 41 527 +1000 4 0 80 71 81 302 +1001 4 0 457 477 41 527 +1002 4 0 647 487 430 479 +1003 4 0 628 373 497 441 +1004 4 0 578 628 441 374 +1005 4 0 410 24 335 350 +1006 4 0 393 311 160 150 +1007 4 0 367 118 137 141 +1008 4 0 343 488 356 396 +1009 4 0 87 72 61 58 +1010 4 0 488 588 356 396 +1011 4 0 476 54 59 347 +1012 4 0 94 353 61 77 +1013 4 0 110 353 87 107 +1014 4 0 251 245 322 201 +1015 4 0 245 179 322 201 +1016 4 0 11 422 486 14 +1017 4 0 287 588 464 528 +1018 4 0 10 467 412 551 +1019 4 0 13 551 412 467 +1020 4 0 371 467 551 13 +1021 4 0 551 10 8 412 +1022 4 0 113 164 361 136 +1023 4 0 425 25 15 26 +1024 4 0 140 348 125 160 +1025 4 0 451 588 528 286 +1026 4 0 180 152 145 141 +1027 4 0 607 16 539 470 +1028 4 0 374 570 400 373 +1029 4 0 373 374 556 400 +1030 4 0 374 373 556 628 +1031 4 0 441 628 578 483 +1032 4 0 497 642 418 629 +1033 4 0 167 89 106 339 +1034 4 0 346 440 390 521 +1035 4 0 369 123 342 375 +1036 4 0 583 382 498 361 +1037 4 0 564 75 72 61 +1038 4 0 564 61 64 75 +1039 4 0 345 517 79 92 +1040 4 0 533 529 223 222 +1041 4 0 498 582 576 375 +1042 4 0 575 376 609 49 +1043 4 0 412 10 8 447 +1044 4 0 561 472 549 468 +1045 4 0 239 322 252 231 +1046 4 0 397 12 4 14 +1047 4 0 367 369 434 576 +1048 4 0 206 313 322 179 +1049 4 0 322 179 313 354 +1050 4 0 12 2 4 7 +1051 4 0 346 638 26 608 +1052 4 0 66 87 57 58 +1053 4 0 72 58 564 61 +1054 4 0 322 207 231 239 +1055 4 0 201 354 322 207 +1056 4 0 239 255 322 201 +1057 4 0 533 402 529 222 +1058 4 0 60 518 564 65 +1059 4 0 11 486 12 14 +1060 4 0 118 168 141 152 +1061 4 0 60 376 564 518 +1062 4 0 576 375 582 115 +1063 4 0 515 34 399 351 +1064 4 0 334 564 64 363 +1065 4 0 311 331 150 305 +1066 4 0 473 538 597 519 +1067 4 0 564 594 575 475 +1068 4 0 36 30 432 410 +1069 4 0 343 396 356 279 +1070 4 0 281 279 356 396 +1071 4 0 281 274 301 356 +1072 4 0 486 7 14 422 +1073 4 0 642 153 585 629 +1074 4 0 153 642 628 629 +1075 4 0 503 447 8 10 +1076 4 0 461 430 620 416 +1077 4 0 493 270 275 280 +1078 4 0 275 493 532 323 +1079 4 0 532 493 282 323 +1080 4 0 461 495 430 416 +1081 4 0 493 532 280 275 +1082 4 0 389 381 47 413 +1083 4 0 49 413 626 527 +1084 4 0 500 189 186 181 +1085 4 0 498 382 582 375 +1086 4 0 410 30 24 377 +1087 4 0 30 410 36 377 +1088 4 0 366 265 279 272 +1089 4 0 608 34 32 31 +1090 4 0 527 40 43 38 +1091 4 0 46 527 41 38 +1092 4 0 43 527 38 41 +1093 4 0 597 639 7 486 +1094 4 0 306 298 336 331 +1095 4 0 11 26 15 543 +1096 4 0 554 11 15 543 +1097 4 0 416 430 620 649 +1098 4 0 291 290 364 327 +1099 4 0 637 498 375 361 +1100 4 0 39 548 33 461 +1101 4 0 422 634 25 543 +1102 4 0 583 582 382 113 +1103 4 0 367 114 118 141 +1104 4 0 473 422 11 554 +1105 4 0 178 197 168 141 +1106 4 0 375 369 123 115 +1107 4 0 91 123 115 375 +1108 4 0 377 350 36 553 +1109 4 0 173 181 516 186 +1110 4 0 110 95 107 87 +1111 4 0 353 107 163 87 +1112 4 0 46 527 42 610 +1113 4 0 500 209 348 202 +1114 4 0 334 61 564 57 +1115 4 0 510 103 140 161 +1116 4 0 160 104 140 133 +1117 4 0 486 11 473 422 +1118 4 0 336 611 331 514 +1119 4 0 576 434 637 369 +1120 4 0 29 466 524 20 +1121 4 0 366 279 265 258 +1122 4 0 366 279 258 274 +1123 4 0 89 484 338 454 +1124 4 0 462 621 568 534 +1125 4 0 133 104 140 103 +1126 4 0 462 534 568 531 +1127 4 0 521 440 390 563 +1128 4 0 383 440 563 390 +1129 4 0 141 154 170 369 +1130 4 0 141 193 369 170 +1131 4 0 173 181 510 516 +1132 4 0 348 510 181 516 +1133 4 0 324 366 276 272 +1134 4 0 415 324 366 323 +1135 4 0 477 527 507 43 +1136 4 0 26 25 440 346 +1137 4 0 430 333 42 479 +1138 4 0 460 452 564 75 +1139 4 0 31 515 32 592 +1140 4 0 181 189 187 500 +1141 4 0 389 527 413 47 +1142 4 0 413 389 626 527 +1143 4 0 376 590 49 575 +1144 4 0 331 611 185 508 +1145 4 0 223 392 407 219 +1146 4 0 223 233 392 219 +1147 4 0 538 648 597 519 +1148 4 0 597 648 538 486 +1149 4 0 557 537 568 499 +1150 4 0 553 39 461 416 +1151 4 0 290 528 451 287 +1152 4 0 554 453 332 560 +1153 4 0 601 467 458 9 +1154 4 0 623 525 535 566 +1155 4 0 566 525 535 526 +1156 4 0 378 106 431 418 +1157 4 0 53 496 352 347 +1158 4 0 564 300 419 72 +1159 4 0 564 452 300 72 +1160 4 0 2 6 7 486 +1161 4 0 421 451 528 286 +1162 4 0 451 528 588 287 +1163 4 0 409 595 433 491 +1164 4 0 79 621 78 401 +1165 4 0 401 621 78 555 +1166 4 0 78 537 555 621 +1167 4 0 599 340 282 301 +1168 4 0 493 599 282 301 +1169 4 0 430 620 42 333 +1170 4 0 565 498 112 637 +1171 4 0 583 498 112 565 +1172 4 0 599 429 536 282 +1173 4 0 599 625 459 429 +1174 4 0 543 554 332 15 +1175 4 0 474 112 637 565 +1176 4 0 364 290 528 327 +1177 4 0 548 461 479 333 +1178 4 0 461 333 430 479 +1179 4 0 383 390 346 440 +1180 4 0 65 60 64 564 +1181 4 0 65 64 75 564 +1182 4 0 383 638 346 390 +1183 4 0 380 468 614 549 +1184 4 0 532 282 276 323 +1185 4 0 157 331 504 150 +1186 4 0 89 454 338 339 +1187 4 0 167 454 89 339 +1188 4 0 8 5 10 551 +1189 4 0 5 520 10 551 +1190 4 0 492 626 545 389 +1191 4 0 389 626 545 469 +1192 4 0 37 33 35 29 +1193 4 0 615 568 499 557 +1194 4 0 500 186 480 202 +1195 4 0 54 56 53 496 +1196 4 0 294 295 291 385 +1197 4 0 295 291 385 327 +1198 4 0 295 294 292 385 +1199 4 0 474 637 361 565 +1200 4 0 497 373 426 540 +1201 4 0 40 29 28 34 +1202 4 0 535 525 581 526 +1203 4 0 328 92 79 517 +1204 4 0 496 56 352 604 +1205 4 0 459 536 646 493 +1206 4 0 459 429 624 536 +1207 4 0 493 536 280 532 +1208 4 0 25 346 26 608 +1209 4 0 351 399 41 38 +1210 4 0 43 41 38 351 +1211 4 0 527 413 47 606 +1212 4 0 308 252 322 231 +1213 4 0 308 255 322 252 +1214 4 0 256 231 252 308 +1215 4 0 256 308 259 247 +1216 4 0 21 30 24 410 +1217 4 0 21 30 562 24 +1218 4 0 315 621 555 568 +1219 4 0 217 219 223 407 +1220 4 0 225 223 219 233 +1221 4 0 407 217 529 223 +1222 4 0 381 452 300 564 +1223 4 0 595 635 433 491 +1224 4 0 414 385 291 327 +1225 4 0 416 39 461 495 +1226 4 0 461 39 548 495 +1227 4 0 461 548 479 495 +1228 4 0 301 282 281 464 +1229 4 0 301 282 285 340 +1230 4 0 315 621 568 462 +1231 4 0 372 289 288 285 +1232 4 0 289 288 285 414 +1233 4 0 431 153 106 378 +1234 4 0 55 641 589 436 +1235 4 0 651 572 638 608 +1236 4 0 564 452 72 75 +1237 4 0 573 534 567 613 +1238 4 0 567 645 600 534 +1239 4 0 499 568 577 537 +1240 4 0 414 327 291 364 +1241 4 0 561 549 614 468 +1242 4 0 338 489 566 64 +1243 4 0 89 484 489 338 +1244 4 0 385 294 465 344 +1245 4 0 445 196 444 209 +1246 4 0 209 550 444 427 +1247 4 0 490 14 11 12 +1248 4 0 490 18 14 12 +1249 4 0 597 648 486 7 +1250 4 0 486 639 7 422 +1251 4 0 639 473 597 631 +1252 4 0 529 491 616 533 +1253 4 0 435 320 125 373 +1254 4 0 616 491 529 541 +1255 4 0 497 628 642 629 +1256 4 0 46 52 413 602 +1257 4 0 623 359 566 338 +1258 4 0 497 506 629 418 +1259 4 0 99 359 623 338 +1260 4 0 65 64 454 75 +1261 4 0 209 617 550 427 +1262 4 0 86 328 144 128 +1263 4 0 570 187 374 368 +1264 4 0 403 86 633 328 +1265 4 0 601 522 458 523 +1266 4 0 604 352 472 56 +1267 4 0 273 312 319 324 +1268 4 0 380 614 63 549 +1269 4 0 561 549 63 614 +1270 4 0 623 525 566 359 +1271 4 0 359 525 566 526 +1272 4 0 566 89 526 489 +1273 4 0 113 382 358 471 +1274 4 0 582 471 382 113 +1275 4 0 523 467 458 601 +1276 4 0 268 308 260 263 +1277 4 0 374 628 556 578 +1278 4 0 498 582 382 583 +1279 4 0 586 645 534 557 +1280 4 0 361 176 369 136 +1281 4 0 277 356 274 279 +1282 4 0 576 637 375 369 +1283 4 0 637 375 369 361 +1284 4 0 373 556 569 400 +1285 4 0 556 373 569 628 +1286 4 0 447 562 24 21 +1287 4 0 47 492 527 507 +1288 4 0 495 39 548 487 +1289 4 0 572 608 651 650 +1290 4 0 541 619 542 574 +1291 4 0 27 562 21 30 +1292 4 0 21 446 562 27 +1293 4 0 517 328 614 79 +1294 4 0 545 530 622 575 +1295 4 0 522 371 523 558 +1296 4 0 523 371 520 558 +1297 4 0 471 91 115 375 +1298 4 0 578 127 628 556 +1299 4 0 127 153 628 556 +1300 4 0 641 413 55 52 +1301 4 0 55 564 436 58 +1302 4 0 564 334 57 594 +1303 4 0 55 641 436 413 +1304 4 0 575 413 49 594 +1305 4 0 15 17 596 560 +1306 4 0 521 440 563 571 +1307 4 0 632 581 62 526 +1308 4 0 285 372 301 340 +1309 4 0 290 451 528 421 +1310 4 0 326 57 564 58 +1311 4 0 205 212 241 204 +1312 4 0 564 452 469 381 +1313 4 0 239 322 207 201 +1314 4 0 223 392 529 407 +1315 4 0 381 564 413 469 +1316 4 0 395 513 311 186 +1317 4 0 389 469 413 626 +1318 4 0 136 361 583 565 +1319 4 0 586 645 567 534 +1320 4 0 32 25 608 346 +1321 4 0 369 367 137 141 +1322 4 0 469 575 545 622 +1323 4 0 593 543 634 422 +1324 4 0 373 569 628 591 +1325 4 0 556 569 153 628 +1326 4 0 196 187 373 570 +1327 4 0 167 454 339 155 +1328 4 0 590 626 575 530 +1329 4 0 536 493 282 532 +1330 4 0 133 140 160 510 +1331 4 0 376 363 64 564 +1332 4 0 209 427 444 587 +1333 4 0 571 440 563 383 +1334 4 0 498 375 576 637 +1335 4 0 531 534 568 579 +1336 4 0 534 568 557 621 +1337 4 0 218 392 643 238 +1338 4 0 568 555 577 537 +1339 4 0 475 609 363 49 +1340 4 0 363 609 475 564 +1341 4 0 393 311 150 305 +1342 4 0 19 425 17 596 +1343 4 0 596 17 603 560 +1344 4 0 522 428 371 558 +1345 4 0 127 628 497 483 +1346 4 0 492 48 545 626 +1347 4 0 21 607 24 580 +1348 4 0 132 117 318 128 +1349 4 0 633 132 547 142 +1350 4 0 437 381 419 413 +1351 4 0 419 381 437 300 +1352 4 0 173 181 186 171 +1353 4 0 405 613 600 534 +1354 4 0 632 526 62 64 +1355 4 0 489 484 64 338 +1356 4 0 600 54 53 621 +1357 4 0 29 20 28 466 +1358 4 0 20 28 466 443 +1359 4 0 49 48 626 590 +1360 4 0 63 345 614 380 +1361 4 0 584 345 63 380 +1362 4 0 470 607 559 478 +1363 4 0 28 23 22 20 +1364 4 0 478 23 22 28 +1365 4 0 473 422 554 631 +1366 4 0 555 537 568 621 +1367 4 0 18 490 14 439 +1368 4 0 596 17 19 603 +1369 4 0 571 440 18 521 +1370 4 0 542 491 616 541 +1371 4 0 534 568 615 557 +1372 4 0 534 568 579 615 +1373 4 0 392 222 229 238 +1374 4 0 626 48 530 590 +1375 4 0 238 406 229 423 +1376 4 0 629 585 642 418 +1377 4 0 418 506 629 378 +1378 4 0 378 431 629 418 +1379 4 0 153 448 628 591 +1380 4 0 591 569 628 153 +1381 4 0 550 209 500 627 +1382 4 0 515 31 32 34 +1383 4 0 209 627 550 617 +1384 4 0 569 556 153 400 +1385 4 0 645 621 557 54 +1386 4 0 529 491 533 223 +1387 4 0 601 1 458 522 +1388 4 0 522 601 1 3 +1389 4 0 359 339 99 106 +1390 4 0 338 99 359 339 +1391 4 0 49 575 626 413 +1392 4 0 473 597 631 453 +1393 4 0 605 564 518 460 +1394 4 0 222 392 402 529 +1395 4 0 113 382 583 361 +1396 4 0 33 335 28 23 +1397 4 0 370 52 594 46 +1398 4 0 408 505 580 607 +1399 4 0 413 640 602 641 +1400 4 0 630 376 564 609 +1401 4 0 49 376 609 363 +1402 4 0 363 376 609 564 +1403 4 0 393 456 311 305 +1404 4 0 218 221 386 643 +1405 4 0 643 386 423 221 +1406 4 0 141 123 369 367 +1407 4 0 498 382 375 361 +1408 4 0 474 637 369 361 +1409 4 0 558 371 520 551 +1410 4 0 558 428 371 551 +1411 4 0 374 441 411 373 +1412 4 0 422 25 26 543 +1413 4 0 25 17 15 634 +1414 4 0 606 44 610 45 +1415 4 0 367 115 369 576 +1416 4 0 367 576 546 115 +1417 4 0 636 573 567 613 +1418 4 0 615 51 579 573 +1419 4 0 50 51 615 636 +1420 4 0 55 413 564 52 +1421 4 0 594 52 413 46 +1422 4 0 564 326 52 57 +1423 4 0 367 434 546 576 +1424 4 0 208 449 379 445 +1425 4 0 379 445 544 208 +1426 4 0 26 439 440 25 +1427 4 0 622 575 605 469 +1428 4 0 636 586 567 573 +1429 4 0 573 586 567 534 +1430 4 0 599 625 340 283 +1431 4 0 605 630 518 564 +1432 4 0 171 510 181 161 +1433 4 0 32 29 38 34 +1434 4 0 402 216 392 222 +1435 4 0 223 222 392 238 +1436 4 0 389 492 527 47 +1437 4 0 389 492 626 527 +1438 4 0 577 555 78 537 +1439 4 0 315 621 401 555 +1440 4 0 15 598 634 560 +1441 4 0 634 17 15 560 +1442 4 0 481 142 328 633 +1443 4 0 128 328 144 138 +1444 4 0 413 610 640 606 +1445 4 0 640 606 610 45 +1446 4 0 379 449 444 445 +1447 4 0 187 449 196 444 +1448 4 0 445 449 444 196 +1449 4 0 605 564 460 469 +1450 4 0 575 564 605 469 +1451 4 0 541 200 619 574 +1452 4 0 564 436 419 413 +1453 4 0 517 482 63 614 +1454 4 0 154 369 141 123 +1455 4 0 583 498 565 361 +1456 4 0 498 361 637 565 +1457 4 0 622 530 630 575 +1458 4 0 21 30 432 27 +1459 4 0 173 510 160 516 +1460 4 0 311 160 348 516 +1461 4 0 485 140 540 373 +1462 4 0 21 505 580 447 +1463 4 0 490 26 439 571 +1464 4 0 379 544 220 208 +1465 4 0 348 516 181 186 +1466 4 0 186 509 311 516 +1467 4 0 209 202 627 617 +1468 4 0 433 635 529 491 +1469 4 0 430 42 620 44 +1470 4 0 649 430 620 44 +1471 4 0 529 635 541 491 +1472 4 0 404 24 410 21 +1473 4 0 404 410 24 335 +1474 4 0 89 338 359 339 +1475 4 0 450 328 482 517 +1476 4 0 517 328 482 614 +1477 4 0 78 59 537 621 +1478 4 0 588 396 281 356 +1479 4 0 286 488 588 356 +1480 4 0 424 543 593 422 +1481 4 0 463 607 408 16 +1482 4 0 389 381 413 469 +1483 4 0 413 469 575 626 +1484 4 0 626 469 575 545 +1485 4 0 554 11 543 422 +1486 4 0 459 624 646 536 +1487 4 0 332 543 593 424 +1488 4 0 631 554 424 422 +1489 4 0 153 431 629 378 +1490 4 0 545 48 530 626 +1491 4 0 626 530 545 575 +1492 4 0 59 621 78 79 +1493 4 0 160 510 348 516 +1494 4 0 626 590 575 49 +1495 4 0 576 434 112 637 +1496 4 0 498 576 112 637 +1497 4 0 346 651 638 608 +1498 4 0 13 442 412 362 +1499 4 0 13 467 412 442 +1500 4 0 132 142 633 128 +1501 4 0 184 180 172 170 +1502 4 0 631 332 424 554 +1503 4 0 531 573 579 51 +1504 4 0 521 571 563 18 +1505 4 0 599 625 282 340 +1506 4 0 622 630 605 575 +1507 4 0 562 442 362 412 +1508 4 0 193 180 170 141 +1509 4 0 50 644 636 615 +1510 4 0 443 466 20 19 +1511 4 0 616 542 533 491 +1512 4 0 413 594 564 52 +1513 4 0 621 53 600 405 +1514 4 0 362 562 446 27 +1515 4 0 403 547 321 481 +1516 4 0 403 481 321 329 +1517 4 0 562 442 412 10 +1518 4 0 493 459 536 599 +1519 4 0 493 599 536 282 +1520 4 0 450 86 328 517 +1521 4 0 413 602 610 46 +1522 4 0 29 23 28 20 +1523 4 0 223 409 433 491 +1524 4 0 621 59 537 54 +1525 4 0 13 362 412 446 +1526 4 0 439 422 11 14 +1527 4 0 639 473 631 422 +1528 4 0 450 612 584 517 +1529 4 0 450 482 612 517 +1530 4 0 413 641 602 52 +1531 4 0 447 10 24 562 +1532 4 0 531 573 534 579 +1533 4 0 380 345 468 604 +1534 4 0 587 427 444 618 +1535 4 0 613 567 600 534 +1536 4 0 218 386 238 643 +1537 4 0 643 238 423 386 +1538 4 0 347 496 352 604 +1539 4 0 63 345 517 614 +1540 4 0 584 612 63 517 +1541 4 0 629 431 585 418 +1542 4 0 153 431 585 629 +1543 4 0 463 539 478 607 +1544 4 0 463 539 607 16 +1545 4 0 564 609 475 575 +1546 4 0 533 529 402 616 +1547 4 0 376 630 564 518 +1548 4 0 645 54 600 621 +1549 4 0 380 468 472 604 +1550 4 0 604 468 472 352 +1551 4 0 380 468 549 472 +1552 4 0 570 187 373 374 +1553 4 0 606 413 641 640 +1554 4 0 413 610 602 640 +1555 4 0 458 467 13 9 +1556 4 0 467 458 13 371 +1557 4 0 11 422 26 543 +1558 4 0 25 17 425 15 +1559 4 0 646 536 280 493 +1560 4 0 646 624 280 536 +1561 4 0 647 430 44 42 +1562 4 0 618 544 220 379 +1563 4 0 648 6 486 7 +1564 4 0 648 6 538 486 +1565 4 0 403 633 547 481 +1566 4 0 403 328 633 481 +1567 4 0 483 127 628 578 +1568 4 0 486 7 12 14 +1569 4 0 53 56 352 496 +1570 4 0 340 288 284 625 +1571 4 0 283 340 284 625 +1572 4 0 561 352 472 468 +1573 4 0 86 450 328 403 +1574 4 0 329 403 481 328 +1575 4 0 455 288 284 372 +1576 4 0 501 288 284 455 +1577 4 0 376 530 575 630 +1578 4 0 630 376 609 575 +1579 4 0 430 479 42 647 +1580 4 0 621 405 600 534 +1581 4 0 22 28 20 443 +1582 4 0 643 238 229 423 +1583 4 0 481 633 547 142 +1584 4 0 558 428 551 652 +1585 4 0 509 611 331 508 +1586 4 0 513 514 331 611 +1587 4 0 509 513 331 611 +1588 4 0 601 9 1 3 +1589 4 0 289 288 344 501 +1590 4 0 515 32 399 34 +1591 4 0 403 321 349 329 +1592 4 0 392 229 643 238 +1593 4 0 618 445 544 379 +1594 4 0 618 587 544 445 +1595 4 0 531 613 534 573 +1596 4 0 629 153 448 628 +1597 4 0 538 473 597 486 +1598 4 0 597 473 639 486 +1599 4 0 650 31 608 346 +1600 4 0 607 505 580 21 +1601 4 0 288 455 289 372 +1602 4 0 289 455 288 501 +1603 4 0 376 530 590 575 +1604 4 0 49 594 475 575 +1605 4 0 356 279 281 274 +1606 4 0 550 209 444 500 +1607 4 0 362 412 446 562 +1608 4 0 529 433 491 223 +1609 4 0 455 372 284 283 +1610 4 0 465 501 455 289 +1611 4 0 465 289 344 501 +1612 4 0 445 209 444 587 +1613 4 0 153 642 127 628 +1614 4 0 294 385 291 414 +1615 4 0 283 625 459 599 +1616 4 0 613 531 51 573 +1617 4 0 636 573 613 51 +1618 4 0 557 621 568 537 +1619 4 0 558 551 520 5 +1620 4 0 500 209 202 627 +1621 4 0 635 200 541 574 +1622 4 0 595 200 635 574 +1623 4 0 558 652 551 5 +1624 4 0 534 579 573 615 +1625 4 0 605 575 630 564 +1626 4 0 31 346 32 608 +1627 4 0 631 424 639 422 +1628 4 0 383 346 638 26 +1629 4 0 469 575 564 413 +1630 4 0 15 560 332 598 +1631 4 0 15 554 332 560 +1632 4 0 586 557 534 615 +1633 4 0 573 586 534 615 +1634 4 0 332 543 598 593 +1635 4 0 543 332 598 15 +1636 4 0 609 575 564 630 +1637 4 0 554 631 332 453 +1638 4 0 424 554 543 422 +1639 4 0 608 346 651 650 +1640 4 0 487 495 430 479 +1641 4 0 645 621 534 557 +1642 4 0 645 621 600 534 +1643 4 0 542 491 541 574 +1644 4 0 541 635 574 491 +1645 4 0 636 644 586 573 +1646 4 0 573 586 615 644 +1647 4 0 543 634 598 593 +1648 4 0 497 127 642 628 +1649 4 0 598 543 15 634 +1650 4 0 25 15 543 634 +1651 4 0 473 519 597 453 +1652 4 0 595 574 635 491 +1653 4 0 636 51 615 573 +1654 4 0 644 573 636 615 +$EndElements +$ElementData +1 +"color" +1 +0.0 +3 +0 +1 +1654 +1 7.56199 +2 4.86806 +3 4.40144 +4 6.42934 +5 4.22059 +6 5.73014 +7 6.38728 +8 6.65278 +9 6.11566 +10 8.59831 +11 4.59846 +12 3.75402 +13 4.81655 +14 5.303 +15 4.23688 +16 4.44352 +17 9.61146 +18 4.02007 +19 6.55381 +20 4.32183 +21 3.77651 +22 4.28126 +23 4.67035 +24 4.25302 +25 3.24949 +26 3.81682 +27 3.6786 +28 5.26567 +29 5.75883 +30 4.40013 +31 4.8604 +32 3.88159 +33 3.62912 +34 6.09732 +35 6.23606 +36 6.81931 +37 3.98474 +38 5.09313 +39 7.92162 +40 5.91342 +41 5.89822 +42 7.79576 +43 3.26766 +44 6.40478 +45 3.30998 +46 5.75804 +47 4.44341 +48 5.56712 +49 7.92901 +50 7.32341 +51 4.11488 +52 7.27876 +53 4.46523 +54 4.41017 +55 4.24074 +56 5.18865 +57 3.67411 +58 3.93323 +59 6.27803 +60 5.7046 +61 5.43246 +62 6.62422 +63 6.87791 +64 4.8315 +65 4.41484 +66 3.44597 +67 4.80585 +68 4.76576 +69 5.09151 +70 3.90176 +71 3.98978 +72 7.05842 +73 5.79771 +74 5.72113 +75 5.39406 +76 8.36837 +77 6.57885 +78 3.81664 +79 5.04602 +80 5.13045 +81 4.17786 +82 4.12193 +83 5.498 +84 3.9477 +85 4.17729 +86 4.53085 +87 4.87674 +88 5.63865 +89 4.91132 +90 5.42233 +91 7.2101 +92 6.62552 +93 5.99626 +94 5.99827 +95 4.64279 +96 4.40763 +97 7.74874 +98 4.60244 +99 4.55322 +100 3.87632 +101 4.43066 +102 3.5908 +103 4.4961 +104 4.6942 +105 6.85876 +106 6.09827 +107 5.34771 +108 3.88554 +109 4.99917 +110 5.07909 +111 5.16529 +112 6.2445 +113 4.05386 +114 4.0937 +115 4.62717 +116 4.31849 +117 3.26285 +118 3.35407 +119 3.68025 +120 5.5668 +121 4.22251 +122 4.99967 +123 4.02172 +124 7.95474 +125 6.88951 +126 5.11647 +127 3.62751 +128 3.75947 +129 5.71937 +130 4.65378 +131 4.22097 +132 3.54665 +133 4.0164 +134 4.14403 +135 5.88228 +136 3.88365 +137 4.9027 +138 3.88649 +139 3.94684 +140 5.61741 +141 4.86852 +142 4.25794 +143 7.6941 +144 4.73617 +145 3.12373 +146 4.88928 +147 3.62576 +148 4.16485 +149 3.9426 +150 3.46852 +151 6.77747 +152 5.33702 +153 6.56503 +154 5.80932 +155 6.15413 +156 6.85355 +157 4.14906 +158 6.14933 +159 6.69641 +160 3.64734 +161 9.61926 +162 4.84044 +163 6.90865 +164 3.44809 +165 7.79131 +166 4.2801 +167 3.52051 +168 5.45391 +169 3.39718 +170 4.71838 +171 3.97902 +172 6.18658 +173 4.17284 +174 3.92603 +175 6.61929 +176 4.47741 +177 5.4168 +178 4.66072 +179 6.78272 +180 8.92575 +181 3.81346 +182 3.82779 +183 3.59616 +184 4.4729 +185 4.12509 +186 9.13405 +187 4.3469 +188 4.17304 +189 3.37722 +190 4.22285 +191 3.89981 +192 3.56114 +193 5.07249 +194 5.73119 +195 3.31977 +196 7.91262 +197 4.91172 +198 4.3087 +199 4.15402 +200 7.6821 +201 4.41955 +202 4.64581 +203 4.16326 +204 7.51723 +205 6.23256 +206 4.63327 +207 4.85318 +208 6.48807 +209 3.61821 +210 5.09043 +211 8.53276 +212 6.52094 +213 3.90421 +214 4.42601 +215 3.83625 +216 5.54714 +217 3.51603 +218 3.84227 +219 5.7805 +220 5.82631 +221 4.20829 +222 5.28021 +223 4.00498 +224 6.02503 +225 5.06898 +226 5.05237 +227 4.69681 +228 4.59421 +229 4.21961 +230 4.26009 +231 5.25661 +232 6.12045 +233 4.26478 +234 3.42011 +235 3.96254 +236 5.39782 +237 5.34452 +238 5.57074 +239 3.58786 +240 5.48832 +241 5.04805 +242 6.99507 +243 4.86669 +244 8.67723 +245 4.42583 +246 6.08779 +247 8.30081 +248 4.11458 +249 7.33372 +250 4.37632 +251 6.55974 +252 4.06411 +253 7.65217 +254 4.98446 +255 7.00166 +256 9.18261 +257 3.97417 +258 3.76504 +259 4.45173 +260 3.78705 +261 8.85178 +262 5.99438 +263 3.68369 +264 4.64732 +265 5.79147 +266 6.364 +267 5.03453 +268 4.96944 +269 4.75356 +270 3.20622 +271 4.24018 +272 4.41709 +273 4.21315 +274 4.38612 +275 6.51163 +276 5.01322 +277 5.46653 +278 3.97587 +279 6.44458 +280 4.97667 +281 5.55967 +282 5.85158 +283 5.0027 +284 3.48534 +285 6.58618 +286 4.80285 +287 5.94949 +288 4.82903 +289 7.5367 +290 5.70127 +291 7.09932 +292 5.78603 +293 5.97275 +294 3.8847 +295 7.18803 +296 4.24715 +297 6.96264 +298 7.0952 +299 4.63648 +300 6.55609 +301 5.16808 +302 5.24241 +303 3.54707 +304 4.3924 +305 4.0213 +306 4.62658 +307 4.81065 +308 4.56642 +309 6.50736 +310 4.75308 +311 3.8215 +312 3.41325 +313 4.08294 +314 4.91393 +315 5.30757 +316 7.02954 +317 5.24187 +318 4.13738 +319 6.58547 +320 3.70239 +321 3.67817 +322 4.58162 +323 5.24492 +324 4.86733 +325 4.91221 +326 4.2757 +327 5.39939 +328 4.61598 +329 8.42673 +330 6.14168 +331 4.57608 +332 3.81451 +333 4.29124 +334 4.12792 +335 5.02872 +336 5.23399 +337 3.38677 +338 4.50817 +339 5.28311 +340 5.64442 +341 4.71327 +342 6.09192 +343 4.17098 +344 7.35127 +345 5.55052 +346 8.62264 +347 7.92427 +348 4.62414 +349 5.61806 +350 5.34776 +351 6.86714 +352 4.07043 +353 3.76518 +354 3.52133 +355 4.0364 +356 4.23061 +357 5.51497 +358 5.34338 +359 5.2446 +360 3.66377 +361 3.61536 +362 4.93218 +363 5.91732 +364 3.99037 +365 6.86673 +366 4.57754 +367 4.54417 +368 3.49705 +369 3.68222 +370 4.05441 +371 3.28484 +372 3.86728 +373 6.47469 +374 3.8287 +375 4.21948 +376 6.50072 +377 5.2599 +378 5.46621 +379 3.90163 +380 8.20664 +381 5.20216 +382 5.3226 +383 4.03878 +384 8.93219 +385 6.79859 +386 5.0444 +387 4.38992 +388 6.97679 +389 3.69486 +390 3.64051 +391 3.67985 +392 6.23422 +393 3.30838 +394 7.50667 +395 3.94216 +396 6.5134 +397 8.60865 +398 4.39139 +399 3.46463 +400 3.90001 +401 4.26802 +402 3.71403 +403 3.59913 +404 3.15595 +405 4.92885 +406 9.80662 +407 3.63884 +408 3.80748 +409 5.15094 +410 6.35325 +411 4.20196 +412 5.86833 +413 5.91247 +414 3.313 +415 3.37645 +416 4.89339 +417 5.19552 +418 6.53485 +419 7.98558 +420 3.6091 +421 4.05488 +422 4.29978 +423 4.68265 +424 8.03386 +425 5.59842 +426 4.70185 +427 3.61697 +428 5.69205 +429 7.16982 +430 4.13106 +431 3.56492 +432 4.22082 +433 4.55629 +434 4.58142 +435 5.53457 +436 6.93426 +437 4.80377 +438 3.84526 +439 3.94317 +440 3.45505 +441 5.16289 +442 3.25289 +443 3.95152 +444 5.40892 +445 6.95209 +446 4.15315 +447 5.02186 +448 4.01812 +449 3.96462 +450 7.14857 +451 4.97123 +452 4.79327 +453 4.80934 +454 7.58936 +455 4.07601 +456 4.83387 +457 4.20561 +458 4.19693 +459 4.28828 +460 6.64926 +461 6.10328 +462 5.14523 +463 3.29956 +464 7.82612 +465 6.51338 +466 5.14228 +467 6.36966 +468 4.00039 +469 5.25401 +470 4.90217 +471 3.91685 +472 4.04775 +473 3.71452 +474 4.00893 +475 6.15397 +476 4.73995 +477 4.49103 +478 6.01817 +479 4.51129 +480 4.45673 +481 4.53029 +482 4.39765 +483 4.84946 +484 4.41482 +485 5.22789 +486 4.83751 +487 4.52841 +488 4.37907 +489 4.53931 +490 3.94812 +491 5.60107 +492 7.82411 +493 6.10887 +494 3.61105 +495 6.22222 +496 5.87689 +497 4.37764 +498 5.74756 +499 5.41576 +500 3.94004 +501 5.49027 +502 4.62278 +503 5.90077 +504 3.72543 +505 8.58284 +506 9.99379 +507 3.93429 +508 7.00354 +509 3.34162 +510 6.26251 +511 4.5708 +512 4.61934 +513 6.10199 +514 7.60203 +515 3.49142 +516 6.17078 +517 5.25425 +518 6.30042 +519 5.72046 +520 4.47283 +521 4.83221 +522 4.41013 +523 5.97733 +524 3.99931 +525 4.76894 +526 3.74452 +527 6.2368 +528 4.09343 +529 6.26363 +530 6.83661 +531 3.96425 +532 3.43579 +533 5.77657 +534 5.34581 +535 4.68041 +536 4.37814 +537 5.99737 +538 5.3648 +539 5.4205 +540 4.22935 +541 5.82056 +542 3.98684 +543 3.28936 +544 4.1958 +545 4.33791 +546 4.85201 +547 5.22988 +548 6.51603 +549 4.38544 +550 4.03691 +551 4.28065 +552 7.54771 +553 5.3477 +554 3.98013 +555 3.65612 +556 3.6305 +557 4.96827 +558 7.0639 +559 5.12306 +560 5.26116 +561 3.98468 +562 4.06433 +563 4.43174 +564 9.65465 +565 4.48661 +566 7.06711 +567 6.01908 +568 5.78751 +569 6.07332 +570 8.58829 +571 7.11434 +572 3.46196 +573 5.46102 +574 6.3086 +575 5.34819 +576 6.91082 +577 4.47437 +578 7.81942 +579 6.82906 +580 4.72318 +581 4.06215 +582 9.60519 +583 5.3436 +584 4.7691 +585 4.475 +586 5.84693 +587 5.8161 +588 4.01326 +589 8.52049 +590 6.06203 +591 3.94 +592 6.42148 +593 6.28834 +594 4.88767 +595 7.62703 +596 7.56987 +597 5.54109 +598 4.11926 +599 6.37613 +600 4.92981 +601 4.80206 +602 3.26213 +603 6.37042 +604 5.17572 +605 3.76555 +606 5.26092 +607 4.19725 +608 3.19057 +609 5.88572 +610 5.22575 +611 3.782 +612 4.38116 +613 8.53952 +614 4.30787 +615 4.10562 +616 7.62857 +617 5.65392 +618 5.96086 +619 4.91053 +620 6.14863 +621 5.91276 +622 4.27409 +623 5.55369 +624 4.8645 +625 4.77293 +626 3.55957 +627 4.11882 +628 3.68402 +629 6.55336 +630 5.93665 +631 6.29134 +632 5.06148 +633 6.32722 +634 3.56814 +635 4.97852 +636 5.319 +637 7.67988 +638 4.9724 +639 3.58948 +640 3.2273 +641 4.94275 +642 6.132 +643 4.23477 +644 3.8824 +645 6.47761 +646 5.83872 +647 6.52367 +648 9.09261 +649 4.02275 +650 4.5423 +651 3.77518 +652 9.34733 +653 4.29857 +654 3.53165 +655 3.69875 +656 8.91855 +657 8.27777 +658 4.2927 +659 5.44146 +660 4.88306 +661 4.61662 +662 4.66585 +663 4.08773 +664 5.47614 +665 4.82537 +666 5.34588 +667 5.09433 +668 4.74203 +669 4.80349 +670 5.17033 +671 5.55982 +672 5.85245 +673 8.50255 +674 5.05679 +675 8.2833 +676 4.20019 +677 6.65706 +678 5.50201 +679 3.83497 +680 8.04853 +681 3.98407 +682 4.14575 +683 4.40359 +684 3.83137 +685 7.5115 +686 4.55691 +687 5.02113 +688 4.10109 +689 3.2165 +690 6.76792 +691 7.39527 +692 5.09019 +693 4.66208 +694 4.89628 +695 3.82454 +696 7.89338 +697 4.34543 +698 4.53367 +699 4.2245 +700 7.97378 +701 5.36364 +702 5.48083 +703 5.18437 +704 7.54515 +705 8.01303 +706 6.9711 +707 5.10957 +708 4.65648 +709 4.17603 +710 3.95182 +711 4.30453 +712 4.83791 +713 5.75603 +714 6.26297 +715 4.26312 +716 4.92191 +717 6.49723 +718 5.39117 +719 7.63936 +720 3.8902 +721 5.26165 +722 3.56636 +723 5.80111 +724 8.11139 +725 6.99287 +726 6.0905 +727 4.48145 +728 6.29626 +729 6.41609 +730 4.82834 +731 4.30295 +732 5.95249 +733 9.1162 +734 7.17952 +735 4.41636 +736 7.00516 +737 5.38428 +738 4.57018 +739 5.16323 +740 6.21328 +741 3.84546 +742 8.92755 +743 4.95277 +744 5.60229 +745 4.74588 +746 4.39131 +747 3.53583 +748 4.71464 +749 3.85774 +750 4.32924 +751 4.21807 +752 5.56949 +753 3.92575 +754 4.08047 +755 4.19341 +756 5.43269 +757 5.08675 +758 7.55608 +759 4.60229 +760 5.26588 +761 6.53396 +762 6.09301 +763 8.49182 +764 3.65278 +765 3.7977 +766 4.72003 +767 5.07267 +768 5.39706 +769 5.74691 +770 7.17011 +771 4.60288 +772 6.53685 +773 5.03197 +774 4.75913 +775 5.21044 +776 8.20214 +777 5.1994 +778 5.72262 +779 5.56165 +780 5.11548 +781 4.91619 +782 4.4872 +783 5.68936 +784 4.47124 +785 5.13239 +786 3.56721 +787 6.21762 +788 7.03673 +789 4.75488 +790 6.58105 +791 6.02163 +792 4.0573 +793 5.61253 +794 4.57518 +795 6.37637 +796 4.44356 +797 4.71151 +798 7.569 +799 4.14096 +800 5.59666 +801 4.97895 +802 3.58641 +803 3.31542 +804 5.39692 +805 4.83649 +806 3.97031 +807 5.44832 +808 4.02433 +809 3.60805 +810 5.34786 +811 3.58587 +812 6.69862 +813 3.32895 +814 4.09119 +815 4.58371 +816 3.80674 +817 6.44114 +818 6.223 +819 4.0441 +820 4.80123 +821 4.30222 +822 6.44328 +823 5.35506 +824 6.92359 +825 3.89947 +826 6.49231 +827 4.93294 +828 4.30558 +829 6.36489 +830 6.66548 +831 4.33778 +832 4.17984 +833 5.47755 +834 6.30491 +835 4.8866 +836 3.97457 +837 5.46085 +838 9.49042 +839 5.90533 +840 4.86468 +841 6.77968 +842 4.50722 +843 6.47377 +844 6.71684 +845 7.28311 +846 4.96895 +847 4.62845 +848 4.76509 +849 4.94072 +850 6.06047 +851 5.03461 +852 4.02971 +853 6.54434 +854 6.22769 +855 4.93337 +856 3.68803 +857 3.53863 +858 3.91408 +859 5.65137 +860 7.37176 +861 4.59552 +862 6.93334 +863 3.44661 +864 6.33348 +865 5.02479 +866 5.35196 +867 4.49256 +868 4.90908 +869 5.13244 +870 6.53011 +871 6.74559 +872 6.30754 +873 4.22522 +874 5.22566 +875 4.48669 +876 6.19697 +877 5.32891 +878 5.90513 +879 5.26841 +880 4.69307 +881 6.53259 +882 5.37303 +883 4.84613 +884 6.84862 +885 8.57067 +886 4.51242 +887 4.09543 +888 3.96732 +889 3.54212 +890 7.13459 +891 3.96056 +892 3.53356 +893 7.88643 +894 3.71017 +895 4.50089 +896 6.13237 +897 9.12911 +898 5.99732 +899 4.20221 +900 5.07845 +901 7.39265 +902 3.4358 +903 6.92631 +904 6.19262 +905 8.37263 +906 3.90019 +907 5.27365 +908 8.43827 +909 4.30468 +910 7.89174 +911 4.55601 +912 5.99339 +913 3.9157 +914 6.4819 +915 5.12264 +916 4.56214 +917 4.68284 +918 3.62525 +919 5.50492 +920 3.3911 +921 5.44747 +922 5.1212 +923 3.91631 +924 4.09731 +925 3.90953 +926 3.24567 +927 3.84614 +928 3.16043 +929 5.57228 +930 5.27177 +931 4.70165 +932 6.21956 +933 6.82471 +934 4.75076 +935 5.36529 +936 7.32308 +937 5.56332 +938 4.4607 +939 4.55218 +940 4.41271 +941 4.16343 +942 3.60628 +943 5.64808 +944 5.0414 +945 4.07399 +946 8.06578 +947 5.13059 +948 3.32765 +949 6.87378 +950 6.8715 +951 5.34151 +952 7.4087 +953 4.97386 +954 4.34552 +955 4.26796 +956 4.19602 +957 3.42375 +958 5.85754 +959 5.66926 +960 8.16791 +961 5.85989 +962 5.27303 +963 4.04843 +964 3.73455 +965 6.69521 +966 3.19527 +967 5.41381 +968 4.9373 +969 3.34371 +970 5.277 +971 5.14515 +972 4.27359 +973 3.45159 +974 4.18209 +975 3.97173 +976 6.6748 +977 5.48345 +978 5.03449 +979 6.2847 +980 4.28563 +981 4.42304 +982 8.30151 +983 8.10918 +984 5.2181 +985 6.07928 +986 7.4987 +987 3.86094 +988 7.79415 +989 4.1437 +990 4.22013 +991 4.84238 +992 4.18954 +993 4.63546 +994 5.03533 +995 5.68754 +996 3.66053 +997 4.99215 +998 3.9023 +999 6.64228 +1000 3.66927 +1001 7.59005 +1002 7.84943 +1003 6.12621 +1004 4.28124 +1005 5.25678 +1006 4.49358 +1007 3.83982 +1008 4.1934 +1009 4.15133 +1010 5.9278 +1011 6.99563 +1012 5.9841 +1013 8.90109 +1014 7.652 +1015 7.06981 +1016 4.2989 +1017 4.43713 +1018 3.94864 +1019 5.25543 +1020 5.67571 +1021 4.55211 +1022 5.55705 +1023 4.35115 +1024 3.53053 +1025 4.95254 +1026 5.0626 +1027 5.91199 +1028 3.64351 +1029 4.37971 +1030 6.08977 +1031 8.17508 +1032 9.08688 +1033 6.27308 +1034 5.95361 +1035 5.76509 +1036 4.96722 +1037 5.54433 +1038 4.46812 +1039 5.33303 +1040 6.1708 +1041 6.72636 +1042 5.29678 +1043 4.55251 +1044 8.94976 +1045 3.51383 +1046 9.65923 +1047 5.82992 +1048 4.65022 +1049 4.9202 +1050 5.80657 +1051 3.98189 +1052 5.41173 +1053 4.62405 +1054 3.74779 +1055 3.72462 +1056 4.19243 +1057 8.98073 +1058 5.19122 +1059 4.03261 +1060 3.37577 +1061 5.38447 +1062 7.73223 +1063 8.13835 +1064 4.25916 +1065 4.74505 +1066 7.41008 +1067 7.34217 +1068 4.67887 +1069 7.30568 +1070 4.68001 +1071 4.1343 +1072 4.30236 +1073 4.91304 +1074 3.81816 +1075 4.33604 +1076 7.30661 +1077 3.71466 +1078 5.48295 +1079 5.02695 +1080 5.64749 +1081 4.97985 +1082 5.0635 +1083 4.18982 +1084 6.63653 +1085 6.50817 +1086 4.06997 +1087 4.6217 +1088 3.9456 +1089 5.86381 +1090 4.34958 +1091 4.72955 +1092 7.68562 +1093 4.76352 +1094 4.38867 +1095 7.24025 +1096 8.56583 +1097 7.12327 +1098 7.63126 +1099 4.98995 +1100 5.51299 +1101 6.22274 +1102 8.55485 +1103 4.67541 +1104 5.56093 +1105 4.11592 +1106 5.39012 +1107 4.91738 +1108 4.55802 +1109 9.81191 +1110 9.03824 +1111 4.91096 +1112 5.68686 +1113 5.43295 +1114 4.5376 +1115 7.76145 +1116 6.56722 +1117 5.56414 +1118 6.48512 +1119 7.08636 +1120 4.86379 +1121 5.06374 +1122 4.43781 +1123 6.37562 +1124 8.00607 +1125 5.72785 +1126 7.44421 +1127 8.55665 +1128 5.86133 +1129 9.30702 +1130 5.39706 +1131 9.72751 +1132 3.48947 +1133 4.01753 +1134 6.24749 +1135 5.18517 +1136 3.7291 +1137 5.12041 +1138 5.72019 +1139 8.40329 +1140 4.29092 +1141 6.32703 +1142 4.81643 +1143 6.2805 +1144 8.28778 +1145 6.11067 +1146 4.67958 +1147 6.84822 +1148 6.91117 +1149 8.73063 +1150 5.19026 +1151 8.76106 +1152 7.46817 +1153 4.01789 +1154 4.79286 +1155 4.32607 +1156 8.23324 +1157 4.8066 +1158 6.2838 +1159 6.4227 +1160 9.33195 +1161 4.68307 +1162 6.92146 +1163 6.30771 +1164 7.57291 +1165 7.22122 +1166 6.39772 +1167 5.60827 +1168 3.81708 +1169 3.25156 +1170 8.08526 +1171 7.77888 +1172 4.56788 +1173 8.09687 +1174 3.49101 +1175 4.88315 +1176 9.9666 +1177 5.09136 +1178 4.89489 +1179 8.84418 +1180 4.97986 +1181 5.33513 +1182 5.84621 +1183 3.85303 +1184 4.81127 +1185 7.16765 +1186 5.06141 +1187 7.20188 +1188 4.7328 +1189 5.06946 +1190 3.66104 +1191 4.29874 +1192 3.89884 +1193 6.80851 +1194 5.53224 +1195 7.4339 +1196 5.48488 +1197 8.32916 +1198 5.44496 +1199 5.953 +1200 7.10064 +1201 4.28803 +1202 5.27418 +1203 3.79067 +1204 3.44724 +1205 4.17183 +1206 7.19842 +1207 4.32375 +1208 3.51299 +1209 7.615 +1210 5.69386 +1211 6.73423 +1212 4.51568 +1213 6.08616 +1214 5.21758 +1215 8.14411 +1216 4.06477 +1217 5.22976 +1218 5.07475 +1219 5.92439 +1220 4.9689 +1221 5.09276 +1222 7.43835 +1223 6.71407 +1224 7.02283 +1225 6.5295 +1226 4.40292 +1227 5.83422 +1228 3.70634 +1229 3.52758 +1230 6.0864 +1231 4.79487 +1232 5.2648 +1233 6.60461 +1234 4.95882 +1235 9.41937 +1236 5.13095 +1237 5.28013 +1238 5.44854 +1239 7.71878 +1240 5.56885 +1241 8.76006 +1242 4.56393 +1243 5.90289 +1244 6.17245 +1245 5.47762 +1246 6.85481 +1247 3.17205 +1248 4.86204 +1249 4.43452 +1250 6.97671 +1251 5.3337 +1252 5.43708 +1253 5.01141 +1254 7.23168 +1255 3.70348 +1256 4.66871 +1257 8.66635 +1258 7.63642 +1259 6.58896 +1260 5.63525 +1261 5.18847 +1262 4.60493 +1263 8.295 +1264 7.64526 +1265 3.59029 +1266 8.30829 +1267 5.61988 +1268 4.40627 +1269 8.59727 +1270 7.237 +1271 5.90024 +1272 4.03286 +1273 4.8429 +1274 7.10562 +1275 6.50655 +1276 4.64487 +1277 4.69878 +1278 7.97432 +1279 4.02501 +1280 5.38605 +1281 4.92341 +1282 5.07646 +1283 3.75685 +1284 5.31243 +1285 5.7707 +1286 5.68964 +1287 5.96062 +1288 7.85077 +1289 8.21576 +1290 6.68323 +1291 4.30884 +1292 4.784 +1293 5.21908 +1294 4.82005 +1295 4.40245 +1296 4.02024 +1297 3.62885 +1298 3.78701 +1299 3.55008 +1300 4.66264 +1301 5.58137 +1302 4.33701 +1303 4.93396 +1304 3.52374 +1305 7.13144 +1306 5.36387 +1307 8.97625 +1308 5.18498 +1309 9.05048 +1310 8.19838 +1311 4.42885 +1312 8.34232 +1313 3.94079 +1314 4.41342 +1315 7.69708 +1316 4.03687 +1317 4.88914 +1318 4.97387 +1319 5.60074 +1320 3.64249 +1321 3.99359 +1322 5.05358 +1323 7.22987 +1324 9.02307 +1325 3.92924 +1326 5.90228 +1327 6.68582 +1328 9.38571 +1329 4.23719 +1330 3.91918 +1331 6.00412 +1332 8.07751 +1333 4.80956 +1334 5.50254 +1335 9.28165 +1336 4.67539 +1337 4.8626 +1338 6.60907 +1339 6.82969 +1340 5.02785 +1341 4.99683 +1342 7.89183 +1343 9.24249 +1344 5.19206 +1345 4.25973 +1346 5.32035 +1347 4.13126 +1348 5.9532 +1349 6.48769 +1350 3.89076 +1351 5.66956 +1352 7.52047 +1353 5.81182 +1354 7.64656 +1355 5.39628 +1356 5.38481 +1357 4.57187 +1358 7.85941 +1359 3.19563 +1360 4.16723 +1361 7.58062 +1362 5.43379 +1363 4.5491 +1364 9.55822 +1365 5.41463 +1366 3.93709 +1367 5.58151 +1368 7.63004 +1369 7.19653 +1370 6.21067 +1371 4.16437 +1372 7.03794 +1373 6.03681 +1374 7.32543 +1375 8.75148 +1376 9.85852 +1377 5.51133 +1378 8.69481 +1379 5.56414 +1380 6.99819 +1381 3.55529 +1382 5.3928 +1383 4.84586 +1384 7.9864 +1385 6.53059 +1386 4.99042 +1387 4.16435 +1388 6.80177 +1389 5.45811 +1390 5.63078 +1391 3.96717 +1392 3.86136 +1393 3.20475 +1394 8.36851 +1395 5.32051 +1396 4.09927 +1397 4.30378 +1398 6.53894 +1399 9.57378 +1400 6.55006 +1401 6.34936 +1402 4.66909 +1403 4.92672 +1404 6.29711 +1405 6.13071 +1406 7.07983 +1407 3.38745 +1408 6.19644 +1409 3.70599 +1410 8.72514 +1411 5.01474 +1412 6.35499 +1413 8.51238 +1414 6.1006 +1415 8.31744 +1416 8.69373 +1417 5.3837 +1418 3.29415 +1419 3.17415 +1420 4.65337 +1421 3.77393 +1422 3.8875 +1423 7.11242 +1424 4.79596 +1425 4.074 +1426 4.91429 +1427 5.40041 +1428 4.50152 +1429 6.82147 +1430 7.03258 +1431 9.84567 +1432 5.28303 +1433 3.28496 +1434 5.3585 +1435 5.80604 +1436 6.24381 +1437 3.80452 +1438 8.7948 +1439 6.69635 +1440 5.38362 +1441 8.19043 +1442 6.65785 +1443 5.14952 +1444 8.66002 +1445 6.98012 +1446 5.82976 +1447 4.7057 +1448 4.19243 +1449 4.46766 +1450 4.94058 +1451 8.7967 +1452 5.51495 +1453 4.0043 +1454 5.16481 +1455 6.42095 +1456 6.01744 +1457 3.71544 +1458 5.73042 +1459 8.12425 +1460 3.95837 +1461 7.51813 +1462 9.24805 +1463 7.61923 +1464 4.43411 +1465 3.83737 +1466 3.95716 +1467 7.15998 +1468 5.65757 +1469 3.42947 +1470 7.66079 +1471 5.68317 +1472 4.17696 +1473 3.43991 +1474 4.08425 +1475 6.28225 +1476 5.03584 +1477 5.6927 +1478 4.82533 +1479 7.60644 +1480 3.80633 +1481 7.85466 +1482 4.0313 +1483 5.53088 +1484 4.79008 +1485 6.91984 +1486 7.05097 +1487 5.06758 +1488 5.28323 +1489 3.97634 +1490 7.07548 +1491 6.99741 +1492 5.39725 +1493 3.70965 +1494 5.20786 +1495 3.35697 +1496 8.30445 +1497 6.24412 +1498 5.02406 +1499 4.3192 +1500 3.75267 +1501 3.75419 +1502 6.70461 +1503 7.29339 +1504 7.25608 +1505 4.67025 +1506 7.00533 +1507 4.95845 +1508 5.9428 +1509 8.22798 +1510 6.09413 +1511 6.69181 +1512 4.68312 +1513 8.54909 +1514 9.17576 +1515 4.67904 +1516 5.70206 +1517 3.82361 +1518 4.83649 +1519 4.49647 +1520 6.62776 +1521 3.87563 +1522 3.82749 +1523 7.136 +1524 5.46372 +1525 7.49927 +1526 4.77056 +1527 6.99557 +1528 5.41681 +1529 5.67049 +1530 9.09783 +1531 6.2033 +1532 5.7676 +1533 6.10859 +1534 5.64874 +1535 4.25459 +1536 4.24224 +1537 7.54998 +1538 4.6898 +1539 3.65217 +1540 6.77849 +1541 7.38216 +1542 5.01269 +1543 9.63731 +1544 5.93312 +1545 6.67582 +1546 4.31103 +1547 7.11233 +1548 9.36116 +1549 5.26081 +1550 5.69302 +1551 3.48767 +1552 6.63839 +1553 6.58539 +1554 7.28664 +1555 3.81367 +1556 4.57632 +1557 5.76642 +1558 5.47675 +1559 4.10006 +1560 7.47012 +1561 4.71169 +1562 7.33109 +1563 3.61097 +1564 7.2049 +1565 5.17177 +1566 5.69784 +1567 5.66136 +1568 5.26364 +1569 5.80611 +1570 6.17947 +1571 7.04854 +1572 8.77365 +1573 4.85623 +1574 3.77604 +1575 4.3199 +1576 5.59875 +1577 7.20581 +1578 8.22279 +1579 6.75557 +1580 6.15071 +1581 8.40391 +1582 5.84813 +1583 6.71808 +1584 9.4805 +1585 5.78575 +1586 5.53995 +1587 6.22247 +1588 6.41044 +1589 4.20686 +1590 5.13741 +1591 9.43675 +1592 4.7142 +1593 3.98455 +1594 7.70331 +1595 5.7983 +1596 5.38736 +1597 6.27297 +1598 5.693 +1599 7.78512 +1600 9.5604 +1601 3.88507 +1602 5.01882 +1603 7.63484 +1604 5.06804 +1605 4.18197 +1606 4.43359 +1607 4.34535 +1608 4.02395 +1609 7.2371 +1610 8.47037 +1611 4.49746 +1612 8.23039 +1613 4.43065 +1614 4.82179 +1615 7.15842 +1616 4.60424 +1617 4.60142 +1618 4.98153 +1619 4.82699 +1620 6.48302 +1621 5.81494 +1622 9.77863 +1623 9.18164 +1624 8.97711 +1625 6.39388 +1626 4.3432 +1627 8.33951 +1628 5.09327 +1629 5.99447 +1630 4.3455 +1631 6.29698 +1632 3.33295 +1633 6.59657 +1634 6.95084 +1635 3.19532 +1636 5.517 +1637 5.79544 +1638 5.11606 +1639 5.09728 +1640 6.96594 +1641 4.43697 +1642 8.62959 +1643 6.33994 +1644 4.6679 +1645 6.9788 +1646 4.62802 +1647 9.58879 +1648 4.3363 +1649 5.16264 +1650 7.16104 +1651 5.92186 +1652 7.45343 +1653 3.24729 +1654 9.37208 +$EndElementData diff --git a/test/user/testdata/shark_22_ascii_fTetWild.xml b/test/user/testdata/shark_22_ascii_fTetWild.xml new file mode 100644 index 00000000..2bead34f --- /dev/null +++ b/test/user/testdata/shark_22_ascii_fTetWild.xml @@ -0,0 +1,25 @@ + + diff --git a/test/user/testdata/shark_22_ascii_gmshApp.msh b/test/user/testdata/shark_22_ascii_gmshApp.msh new file mode 100644 index 00000000..9cf34972 --- /dev/null +++ b/test/user/testdata/shark_22_ascii_gmshApp.msh @@ -0,0 +1,2315 @@ +$MeshFormat +2.2 0 8 +$EndMeshFormat +$Nodes +652 +1 -0.07334359999999999 0.08167480000000001 0.056402 +2 -0.07291259999999999 0.0537921 0.00170478 +3 -0.072634 0.0799069 0.0578949 +4 -0.0715817 0.0520377 0.00292576 +5 -0.0701949 0.08025690000000001 0.0450431 +6 -0.06876980000000001 0.060971 0.00326551 +7 -0.06778000000000001 0.060358 0.00473741 +8 -0.06727959999999999 0.08092489999999999 0.0425553 +9 -0.0658074 0.0806443 0.0552302 +10 -0.064933 0.0788176 0.0453762 +11 -0.0636555 0.0610198 0.00141989 +12 -0.0636111 0.0566004 -0.000556663 +13 -0.0636791 0.0819076 0.0524468 +14 -0.0623445 0.0580268 0.00335683 +15 -0.0624856 0.06710579999999999 0.00581638 +16 -0.0601398 0.0781111 0.0317589 +17 -0.0599443 0.0685632 0.009924489999999999 +18 -0.0592787 0.0571239 0.00105116 +19 -0.0587906 0.07199990000000001 0.0117948 +20 -0.0575605 0.0730663 0.016213 +21 -0.057624 0.0811803 0.0403639 +22 -0.0572339 0.0769387 0.0223219 +23 -0.0559974 0.0749629 0.0235691 +24 -0.0542321 0.0763209 0.0344665 +25 -0.0540672 0.0649483 0.008218130000000001 +26 -0.0541685 0.06611350000000001 0.00437935 +27 -0.0532966 0.0805356 0.0466758 +28 -0.0517252 0.07611850000000001 0.0183218 +29 -0.0505257 0.06887699999999999 0.0152572 +30 -0.0503803 0.07726379999999999 0.0406423 +31 -0.0472855 0.0641041 0.00381053 +32 -0.0469016 0.0648796 0.00821733 +33 -0.0474599 0.07272679999999999 0.0265623 +34 -0.0464733 0.070912 0.0103373 +35 -0.0444756 0.07556740000000001 0.0221683 +36 -0.0440208 0.07743129999999999 0.0371107 +37 -0.0434135 0.0685101 0.0213943 +38 -0.0425401 0.0668787 0.0159114 +39 -0.0405353 0.07301630000000001 0.0309862 +40 -0.0386417 0.073548 0.0160682 +41 -0.037401 0.0664899 0.0122191 +42 -0.0358693 0.06894450000000001 0.0243885 +43 -0.0351058 0.06877709999999999 0.0124837 +44 -0.0333614 0.07116500000000001 0.0238503 +45 -0.0325564 0.0696271 0.024504 +46 -0.032455 0.0625178 0.0200737 +47 -0.0305469 0.0729973 0.0173921 +48 -0.0276941 0.06523859999999999 0.0128238 +49 -0.0272717 0.0628782 0.0141328 +50 -0.0263428 0.00735496 0.00505748 +51 -0.0256055 0.00658056 0.00327552 +52 -0.0252856 0.0610141 0.0227762 +53 -0.0250237 -0.00678856 0.00359213 +54 -0.0242889 -0.00589458 0.00589675 +55 -0.0216872 0.0639735 0.0255561 +56 -0.0215721 -0.0119744 0.00619585 +57 -0.0195136 0.0542304 0.0216195 +58 -0.0168343 0.06495339999999999 0.0236547 +59 -0.0161373 -0.00420129 0.00881529 +60 -0.0148726 0.0585475 0.0106707 +61 -0.0140647 0.0517836 0.0159197 +62 -0.0142986 0.0543801 0.0051496 +63 -0.0139611 -0.0178642 0.00651265 +64 -0.0139803 0.0554055 0.0115694 +65 -0.0124373 0.0606817 0.0122622 +66 -0.0127423 0.0580719 0.0285553 +67 -0.0127412 -0.07042320000000001 0.0234664 +68 -0.0126173 -0.0801905 0.022154 +69 -0.0125269 0.0592002 0.0346418 +70 -0.0122498 -0.080596 0.0191154 +71 -0.0121442 -0.0691943 0.0191352 +72 -0.0123618 0.0658492 0.0197519 +73 -0.0121018 -0.063334 0.0245151 +74 -0.0118539 0.0462485 0.0243954 +75 -0.0111067 0.0637388 0.0161162 +76 -0.0110042 -0.0624802 0.0276395 +77 -0.0109072 0.046219 0.0183571 +78 -0.0107037 -0.000325242 0.00950432 +79 -0.010183 -0.0121386 0.00674337 +80 -0.009774420000000001 -0.0638147 0.0162637 +81 -0.0097669 -0.06993340000000001 0.0156591 +82 -0.00942656 -0.0836042 0.0182705 +83 -0.009320999999999999 -0.0852334 0.0216727 +84 -0.00803502 0.0401179 0.0263407 +85 -0.00857808 -0.0579335 0.0163943 +86 -0.007931580000000001 -0.0190616 0.0121625 +87 -0.00782675 0.0573514 0.028038 +88 -0.00773028 -0.0620746 0.0302044 +89 -0.00764665 0.0537773 0.00961295 +90 -0.00721562 -0.0507362 0.0224357 +91 -0.00717408 -0.0528249 0.0179333 +92 -0.00651588 -0.00739691 0.013024 +93 -0.00691116 -0.00014073 0.00823716 +94 -0.00661131 0.044183 0.0123 +95 -0.00658663 0.0535365 0.0326225 +96 -0.00630954 -0.08506569999999999 0.0194796 +97 -0.00616497 -0.0797841 0.0261073 +98 -0.00582999 -0.0494502 0.0287705 +99 -0.00563359 0.0476479 0.00934546 +100 -0.00506609 -0.0425596 0.0250833 +101 -0.00453974 -0.0405694 0.0173853 +102 -0.00447266 0.0319291 0.0205877 +103 -0.00434886 0.0267225 0.00648417 +104 -0.00418386 0.0253438 0.008421959999999999 +105 -0.0041733 -0.0606038 0.0122716 +106 -0.00385183 0.0479538 0.00869149 +107 -0.00333705 0.051389 0.031593 +108 -0.00333565 -0.06938809999999999 0.0119551 +109 -0.00333748 -0.0650683 0.0110291 +110 -0.00292457 0.0475597 0.0319288 +111 -0.00280471 -0.0353375 0.0238411 +112 -0.00273019 -0.0493159 0.0135756 +113 -0.00255346 -0.0452657 0.0126112 +114 -0.00249178 -0.0598565 0.010934 +115 -0.00247351 -0.0533955 0.0149632 +116 -0.00280465 0.0288144 0.0300227 +117 -0.00225175 -0.030519 0.0236922 +118 -0.00205777 -0.0595101 0.00715068 +119 -0.0018581 -0.0627033 0.0116048 +120 -0.00150112 -0.0384203 0.0313885 +121 -0.00143547 -0.0337232 0.0176227 +122 -0.00136747 -0.062725 0.0150152 +123 -0.000884775 -0.0587825 0.0143119 +124 -0.000624659 -0.0247814 0.0257906 +125 -0.000489974 0.0225414 0.0188523 +126 -6.05566e-05 0.0171338 0.0234086 +127 0.00150381 0.0360475 0.00675461 +128 0.000282178 -0.0241462 0.0174969 +129 0.000347869 -0.06752370000000001 0.0324883 +130 0.000429839 -0.0422219 0.0349169 +131 0.00028168 -0.0273698 0.0312235 +132 0.000952705 -0.0267391 0.0143612 +133 0.00105244 0.0186951 0.00689988 +134 0.0011109 -0.0779453 0.014663 +135 0.00137887 0.00842564 0.0258445 +136 0.00107238 -0.0462225 0.00980545 +137 0.00158113 -0.0561697 0.005809 +138 0.00165921 -0.0142314 0.0114909 +139 0.00169065 -0.00330978 0.027848 +140 0.0017282 0.0264299 0.00972258 +141 0.00196109 -0.062067 0.0125082 +142 0.00198494 -0.0249792 0.0122768 +143 0.00206797 -0.0322322 0.0125632 +144 0.00219287 -0.00991015 0.0199027 +145 0.00223228 -0.065619 0.00972103 +146 0.00226787 -0.06664 0.0139131 +147 0.00233081 0.009707510000000001 0.0349608 +148 0.0023033 -0.0550711 0.0357611 +149 0.00284591 -0.06958739999999999 0.0109337 +150 0.00313658 0.0123831 0.0152878 +151 0.00325266 -0.000639164 0.0164744 +152 0.00354678 -0.0651674 0.00553443 +153 0.00434877 0.0392681 0.00656793 +154 0.0034004 -0.0624097 0.0143354 +155 0.00410027 0.052311 0.0146156 +156 0.00425687 -0.0110681 0.0377954 +157 0.0043501 -0.0020508 0.015115 +158 0.00444422 -0.0785667 0.0168482 +159 0.00471578 -0.008727459999999999 0.0133588 +160 0.00486541 0.0192794 0.0102326 +161 0.00475235 0.0259901 0.00777948 +162 0.00497525 -0.0797755 0.0244877 +163 0.0052286 0.0545416 0.0234287 +164 0.00513856 -0.0361953 0.00904286 +165 0.00543656 -0.016404 0.0117933 +166 0.00521097 0.0361763 0.0357574 +167 0.00563068 0.0458779 0.0101474 +168 0.00602624 -0.0598053 0.00448538 +169 0.00669265 -0.0730234 0.0300997 +170 0.00671975 -0.0647944 0.0149968 +171 0.00743572 0.0219428 0.00498754 +172 0.00806977 -0.06766220000000001 0.0106835 +173 0.008580020000000001 0.0185363 0.00804532 +174 0.00900922 -0.0527441 0.0382868 +175 0.00967438 -0.0310472 0.0412759 +176 0.009690270000000001 -0.0470756 0.00574739 +177 0.009825469999999999 -0.0777201 0.0238208 +178 0.010337 -0.0646559 0.00738197 +179 0.0103691 -0.0715108 0.0301524 +180 0.0108524 -0.06519229999999999 0.0107074 +181 0.0112352 0.0223598 0.00496048 +182 0.0115762 0.0360388 0.034027 +183 0.011811 0.0150563 0.0411225 +184 0.0119389 -0.07108730000000001 0.0142927 +185 0.011481 0.000850754 0.00890493 +186 0.0122581 0.0177891 0.00726338 +187 0.0126044 0.0285097 0.0071727 +188 0.0126077 -0.0410848 0.00487059 +189 0.01325 0.0245576 0.00385279 +190 0.0133342 -0.0301914 0.00695184 +191 0.0134526 -0.00467313 0.044297 +192 0.0140263 0.0415073 0.0128325 +193 0.0139319 -0.0627506 0.0126489 +194 0.0144402 0.0213321 0.0408733 +195 0.0145153 -0.0120242 0.00709154 +196 0.0145254 0.0314471 0.00762861 +197 0.0143606 -0.0539791 0.00638859 +198 0.0153705 -0.0588177 0.00913193 +199 0.0158483 0.0424843 0.0267153 +200 0.0161677 0.0082135 0.0752128 +201 0.0160709 -0.0693691 0.0267104 +202 0.0163112 0.021127 0.00658374 +203 0.0163956 0.0418119 0.0180916 +204 0.0166653 0.00513625 0.0449469 +205 0.0171438 -0.009394380000000001 0.0462661 +206 0.0174416 -0.0497054 0.0373642 +207 0.0174198 -0.06569369999999999 0.0159871 +208 0.0177387 0.0346114 0.0053358 +209 0.0178439 0.0247259 0.00729322 +210 0.018247 0.0346901 0.00258831 +211 0.0182074 -0.0318958 0.0424624 +212 0.0183988 -0.00142899 0.0496692 +213 0.0188182 -0.018825 0.0447569 +214 0.0188285 0.0147456 0.0461032 +215 0.0188626 0.015416 0.041072 +216 0.0190811 -0.00419709 0.06868580000000001 +217 0.0195945 0.0084326 0.064095 +218 0.0197498 -0.00217441 0.0583864 +219 0.0198208 0.00539755 0.0587622 +220 0.0200137 0.0324539 0.00354185 +221 0.020151 -0.0145671 0.0500049 +222 0.0203386 -0.00326709 0.07024469999999999 +223 0.0209148 0.00523036 0.0681576 +224 0.0208447 0.0121045 0.0546374 +225 0.0209724 0.009706330000000001 0.0633876 +226 0.020604 -0.0121123 0.00591309 +227 0.0212498 -0.0289526 0.00565549 +228 0.0216078 -0.0380775 0.00479088 +229 0.0216875 -0.00997672 0.0619769 +230 0.0220658 0.00705093 0.0456869 +231 0.0223002 -0.0558455 0.0110476 +232 0.0223137 -0.0154618 0.0494217 +233 0.0229336 0.00417573 0.0589573 +234 0.0231427 0.0278288 0.0125965 +235 0.0231751 0.027241 0.0309726 +236 0.0233259 0.0160686 0.00756079 +237 0.0234095 0.0318943 0.0199392 +238 0.0234462 -0.00393483 0.0583985 +239 0.0235915 -0.0597066 0.0170609 +240 0.0240196 -0.0108777 0.0466362 +241 0.024123 -0.00330273 0.0464733 +242 0.0242099 -0.0321428 0.0398591 +243 0.0244244 0.00347947 0.0416421 +244 0.024564 -0.0175604 0.0433407 +245 0.0253979 -0.0453083 0.0344803 +246 0.0256103 0.0267734 0.0284514 +247 0.0259312 -0.0445208 0.00878379 +248 0.025959 -0.0133125 0.00624018 +249 0.0265967 -0.0369666 0.00635268 +250 0.0273245 -0.0066598 0.0412078 +251 0.0277597 -0.0467651 0.0304517 +252 0.0275944 -0.0515878 0.0207552 +253 0.0282687 0.0208205 0.0174814 +254 0.0290859 0.0112094 0.012597 +255 0.0293048 -0.0474855 0.0256026 +256 0.0296506 -0.0466043 0.0156453 +257 0.0304236 0.0134394 0.031696 +258 0.0304518 -0.0291908 0.00746031 +259 0.03126 -0.044124 0.016095 +260 0.0321715 -0.043346 0.0242104 +261 0.0322352 -0.0402733 0.0141242 +262 0.0323149 0.01052 0.0200521 +263 0.0324768 -0.0397188 0.0271188 +264 0.0325431 -0.0291932 0.0340382 +265 0.0332479 -0.0329826 0.0117351 +266 0.0338676 -0.0346121 0.0252676 +267 0.0341522 -0.00293196 0.033596 +268 0.0341882 -0.0361716 0.0179088 +269 0.0344969 -0.0256263 0.0309923 +270 0.0345138 -0.00958586 0.0123416 +271 0.0348872 -0.0128566 0.0339912 +272 0.0349524 -0.0273994 0.0177976 +273 0.0349556 -0.000677158 0.0209767 +274 0.0350004 -0.028049 0.008761420000000001 +275 0.0353194 -0.0100316 0.0154749 +276 0.0354214 -0.0195455 0.0173172 +277 0.0355775 -0.0309821 0.0107592 +278 0.0360305 -0.0150581 0.0232372 +279 0.0363938 -0.0285041 0.0132933 +280 0.0374738 -0.00607371 0.0123945 +281 0.041317 -0.0210454 0.0131228 +282 0.0425886 -0.0120136 0.0129537 +283 0.0475164 -0.00753527 0.00853843 +284 0.0492593 -0.00704914 0.009380670000000001 +285 0.0496752 -0.0170405 0.0106038 +286 0.0498676 -0.0259318 0.00619626 +287 0.052402 -0.022331 0.00866719 +288 0.0516897 -0.011391 0.0103437 +289 0.0559595 -0.0106346 0.00698866 +290 0.0596531 -0.0214295 0.0059579 +291 0.066312 -0.0158462 0.00759335 +292 0.0672852 -0.00331292 0.00667068 +293 0.0687074 -0.0027598 0.00829441 +294 0.0687083 -0.008451500000000001 0.00881385 +295 0.07028570000000001 -0.00694567 0.00665748 +296 0.02471 0.00101921 0.00688758 +297 0.00641783 -0.0341512 0.0233596 +298 0.024018 0.00854392 0.00722419 +299 0.0251696 0.009421270000000001 0.00784613 +300 -0.019815 0.0686939 0.0189821 +301 0.0416697 -0.017118 0.00864259 +302 -0.00440288 -0.06984319999999999 0.0205811 +303 -0.0033606 0.0600219 0.0217676 +304 0.0268544 0.00322876 0.008082499999999999 +305 0.00855449 0.0107052 0.00928038 +306 0.0219179 0.00585482 0.0121236 +307 0.0199208 0.0175811 0.0336776 +308 0.0210521 -0.0362113 0.0256186 +309 0.0339797 -0.00194129 0.0163861 +310 0.03202 0.000337126 0.0126992 +311 0.0119633 0.0163586 0.0147908 +312 0.0248778 0.0056119 0.0321775 +313 0.00892971 -0.0563678 0.0287948 +314 0.0174837 0.027107 0.0210333 +315 -0.0170518 0.00346089 0.00554363 +316 0.0144974 -0.0120686 0.0314959 +317 0.00336155 -0.00103205 0.0364574 +318 0.00707711 -0.0204903 0.0185209 +319 0.010517 -0.00309481 0.0232445 +320 -0.00559352 0.0373259 0.0172753 +321 -0.00523735 -0.0230725 0.0111224 +322 0.0151072 -0.0538804 0.0213778 +323 0.0347571 -0.0188174 0.0105515 +324 0.0278657 -0.0183642 0.0156758 +325 -0.00338013 -0.0543805 0.0329679 +326 -0.0196332 0.0593213 0.0251138 +327 0.06481629999999999 -0.0143432 0.00627944 +328 -0.00336175 -0.0187472 0.00979996 +329 -0.0059938 -0.0214388 0.00941436 +330 0.0204933 0.0262773 0.00994486 +331 0.0153554 0.00838654 0.0105168 +332 -0.064082 0.064994 0.00682263 +333 -0.0406296 0.0703091 0.0249838 +334 -0.0197677 0.0563929 0.0156108 +335 -0.0506931 0.0781816 0.0304629 +336 0.0171972 -0.00100568 0.011485 +337 0.0314619 -0.0225976 0.00774901 +338 -0.00980694 0.0515267 0.0104574 +339 -0.00435185 0.0493969 0.0137744 +340 0.0449063 -0.0117353 0.00859937 +341 0.00159087 -0.0450385 0.027858 +342 -0.00469537 -0.06372510000000001 0.0233918 +343 0.0424219 -0.0285632 0.00857374 +344 0.0603894 -0.00835109 0.009350529999999999 +345 -0.0147113 -0.0156046 0.009183759999999999 +346 -0.0528157 0.0611754 0.00480955 +347 -0.0173765 -0.008871489999999999 0.00520522 +348 0.0108104 0.02268 0.0130558 +349 -0.00899905 -0.0208443 0.00915416 +350 -0.0449914 0.0768094 0.0302276 +351 -0.0408502 0.06658 0.008368489999999999 +352 -0.0199988 -0.0118916 0.004906 +353 0.00337131 0.0455887 0.0238561 +354 0.00477413 -0.0721541 0.0211645 +355 -0.00344193 -0.049333 0.032475 +356 0.0427245 -0.0268877 0.00738607 +357 0.0272704 -0.0238375 0.00669928 +358 -0.00610544 -0.0476638 0.0181008 +359 -0.00760153 0.0503529 0.00747858 +360 0.0131109 -0.0422224 0.0405109 +361 0.00214561 -0.0490294 0.0151357 +362 -0.0598224 0.0805424 0.0511855 +363 -0.0204542 0.0588165 0.013102 +364 0.059357 -0.0190886 0.00813027 +365 -0.00100716 0.0422264 0.0325724 +366 0.0325535 -0.0244764 0.012522 +367 -0.000431427 -0.0574818 0.0137747 +368 0.0114251 0.0275734 0.00440942 +369 0.00337666 -0.0559724 0.0148659 +370 -0.0262911 0.0586227 0.0207785 +371 -0.0699467 0.0813567 0.0499003 +372 0.0494602 -0.0133111 0.00757754 +373 0.00758285 0.0333008 0.0104911 +374 0.00657287 0.032122 0.00603963 +375 0.000332803 -0.0511328 0.0180756 +376 -0.021764 0.0620607 0.0118108 +377 -0.0454672 0.075167 0.035911 +378 0.00139884 0.045926 0.0128133 +379 0.0176314 0.0311493 0.00370344 +380 -0.0159418 -0.0158578 0.00793814 +381 -0.0229387 0.06916410000000001 0.0166572 +382 -0.00133409 -0.0449329 0.0187829 +383 -0.0538019 0.0611146 0.00198764 +384 0.0305208 -0.00256491 0.0101919 +385 0.0623596 -0.00697151 0.00683979 +386 0.0236819 -0.00777996 0.0526871 +387 0.0118138 -0.0144241 0.0430193 +388 0.0137156 -0.00365078 0.00732253 +389 -0.0257884 0.0686739 0.0150694 +390 -0.0530331 0.060812 0.00248197 +391 -0.000421194 -0.0523335 0.008791770000000001 +392 0.0193846 -0.00072024 0.0649221 +393 0.00485856 0.0133946 0.0114741 +394 -0.0053823 -0.0743714 0.0141262 +395 0.016958 0.0166471 0.00740593 +396 0.0429338 -0.0266961 0.0110582 +397 -0.06504749999999999 0.05473 0.00191127 +398 0.00924818 0.0356698 0.00715588 +399 -0.042468 0.0652669 0.00790867 +400 0.00699205 0.0348997 0.00576165 +401 -0.012123 0.00171435 0.00688121 +402 0.017741 0.00126373 0.0717161 +403 -0.00477874 -0.0228765 0.0123522 +404 -0.05496 0.0793832 0.0329037 +405 -0.0253736 -0.000654191 0.00342534 +406 0.0220159 -0.0128389 0.0555838 +407 0.0187915 0.00366305 0.06539010000000001 +408 -0.0635923 0.0794618 0.0351284 +409 0.0187293 0.00901455 0.0689246 +410 -0.0507436 0.0790633 0.0364811 +411 0.00440962 0.0291856 0.00589534 +412 -0.0610541 0.08157639999999999 0.0467801 +413 -0.0264169 0.06418980000000001 0.0180225 +414 0.0590681 -0.0129818 0.009692930000000001 +415 0.0316732 -0.013669 0.008927310000000001 +416 -0.0368828 0.0732351 0.028231 +417 0.0147007 -0.0293577 0.0425282 +418 -0.00226105 0.042112 0.008184220000000001 +419 -0.022404 0.068624 0.0211714 +420 0.018834 0.0296379 0.0101126 +421 0.0545664 -0.023882 0.00596013 +422 -0.0610274 0.0626039 0.00623226 +423 0.0209345 -0.0123916 0.0558755 +424 -0.064258 0.0639612 0.00701622 +425 -0.0530259 0.07099660000000001 0.0104874 +426 -0.000350232 0.0328643 0.009503569999999999 +427 0.0179821 0.0260225 0.00525665 +428 -0.071629 0.0809096 0.0500374 +429 0.0431333 -0.00662611 0.0109755 +430 -0.0367738 0.072104 0.0272887 +431 -0.00147996 0.0424733 0.00778004 +432 -0.0489442 0.0792518 0.0424775 +433 0.0178184 0.008309230000000001 0.0698262 +434 -0.00256208 -0.0518644 0.0119693 +435 -0.0024457 0.0347988 0.0115191 +436 -0.0226391 0.067054 0.0236986 +437 -0.0250562 0.070839 0.0181046 +438 0.0157661 -0.010775 0.0444953 +439 -0.0587069 0.0610686 0.00549325 +440 -0.0561989 0.0607157 0.00436391 +441 0.0028322 0.0311045 0.0076099 +442 -0.061857 0.079748 0.0514834 +443 -0.0580072 0.07448539999999999 0.0170926 +444 0.017366 0.0281829 0.00449304 +445 0.0175246 0.0303053 0.00632184 +446 -0.0583716 0.0812348 0.0494755 +447 -0.06276379999999999 0.08110589999999999 0.0418948 +448 0.009583370000000001 0.0391723 0.00889538 +449 0.0164997 0.0327763 0.00400793 +450 -0.0100537 -0.019407 0.0104569 +451 0.0535082 -0.023589 0.00757618 +452 -0.0184567 0.0672393 0.0165986 +453 -0.0660887 0.06395149999999999 0.00557639 +454 -0.008500499999999999 0.0591911 0.0132991 +455 0.0527123 -0.00658592 0.00801901 +456 0.00664445 0.0147496 0.00979726 +457 -0.0323364 0.06468409999999999 0.013176 +458 -0.06849810000000001 0.0817682 0.0541475 +459 0.0424951 -0.00680449 0.0104665 +460 -0.01583 0.06382989999999999 0.0140017 +461 -0.0408586 0.07478079999999999 0.0276312 +462 -0.0213675 0.00505684 0.00440033 +463 -0.0609542 0.0784149 0.029815 +464 0.0458286 -0.0196104 0.0115924 +465 0.0619857 -0.0044448 0.00717137 +466 -0.0549453 0.0736446 0.0144159 +467 -0.0660739 0.0797747 0.0511232 +468 -0.0150243 -0.0138696 0.00597473 +469 -0.0208919 0.06642729999999999 0.014553 +470 -0.0583912 0.07667309999999999 0.0277458 +471 -0.00499489 -0.0492059 0.0154875 +472 -0.0177596 -0.0149926 0.00640227 +473 -0.0656257 0.0638276 0.00437301 +474 -0.00111824 -0.0505712 0.010634 +475 -0.0234714 0.0595273 0.0150887 +476 -0.0117477 -0.00786715 0.0107629 +477 -0.0329423 0.0662408 0.012525 +478 -0.0588644 0.0778049 0.0265316 +479 -0.038272 0.07101209999999999 0.0277124 +480 0.0147178 0.0228905 0.00513556 +481 -0.00242697 -0.0228032 0.0106496 +482 -0.00998317 -0.0196685 0.00798312 +483 0.00194711 0.0338412 0.00734265 +484 -0.0101071 0.0571173 0.0108272 +485 -0.000192036 0.0305177 0.010316 +486 -0.06622359999999999 0.0609953 0.00234663 +487 -0.0383437 0.071981 0.0290737 +488 0.0464353 -0.0271448 0.00729223 +489 -0.0113654 0.0558876 0.00985606 +490 -0.0600686 0.0581853 0.00037707 +491 0.0184892 0.00651809 0.072001 +492 -0.0272353 0.0661385 0.0125002 +493 0.0386787 -0.009397559999999999 0.0110365 +494 -0.00702298 -0.0554164 0.0301677 +495 -0.0387296 0.0725599 0.0291973 +496 -0.0195884 -0.009713039999999999 0.00731553 +497 0.0009803979999999999 0.0340005 0.008311529999999999 +498 -0.00251349 -0.0493306 0.0137872 +499 -0.0208118 0.00468072 0.00662791 +500 0.0145465 0.0247675 0.00685396 +501 0.0539643 -0.00601143 0.00911787 +502 0.0615879 -0.00432066 0.00875869 +503 -0.0649217 0.0800024 0.0383643 +504 0.00460493 0.008497380000000001 0.0127005 +505 -0.0606311 0.0803611 0.0379233 +506 -0.00316884 0.0400824 0.00969248 +507 -0.0308482 0.067467 0.0126012 +508 0.0120049 0.00511369 0.00824306 +509 0.0117314 0.0134932 0.00784586 +510 0.0067401 0.0222359 0.00786688 +511 0.000365941 0.0444987 0.0334101 +512 0.00589042 0.0427357 0.0325284 +513 0.0134556 0.013691 0.0071386 +514 0.0155774 0.00572549 0.00675779 +515 -0.0442054 0.0654197 0.00607699 +516 0.00863004 0.0184766 0.00878081 +517 -0.0111016 -0.0170398 0.0107756 +518 -0.0162643 0.06208 0.0123266 +519 -0.06706429999999999 0.0628756 0.0047451 +520 -0.0673064 0.07917689999999999 0.0489333 +521 -0.0566743 0.0588231 0.00264455 +522 -0.07138410000000001 0.080001 0.0523997 +523 -0.0690781 0.0794039 0.0521145 +524 -0.0589744 0.07029879999999999 0.0123753 +525 -0.0108026 0.05228 0.00636676 +526 -0.0113486 0.0541547 0.00728553 +527 -0.0299136 0.06862409999999999 0.0165753 +528 0.0505332 -0.0225927 0.00635398 +529 0.0180077 0.0031318 0.07043870000000001 +530 -0.0235313 0.0640143 0.012641 +531 -0.0235569 0.00584404 0.00381922 +532 0.0384718 -0.0113423 0.0144484 +533 0.0182407 0.00232532 0.0728388 +534 -0.0235752 0.00407866 0.00373027 +535 -0.011585 0.0522432 0.00647843 +536 0.0400312 -0.00904366 0.0126741 +537 -0.0178591 -0.000359808 0.00797485 +538 -0.067167 0.06255139999999999 0.00392853 +539 -0.0596438 0.0779391 0.0290601 +540 0.0013543 0.0302152 0.00901705 +541 0.0168301 0.00522322 0.0737244 +542 0.0174324 0.00448014 0.0738384 +543 -0.0618546 0.0649931 0.00590465 +544 0.0194429 0.0304209 0.00452872 +545 -0.0236633 0.0648084 0.0124456 +546 -0.00249493 -0.0562542 0.012985 +547 -0.0025263 -0.0246783 0.0125409 +548 -0.0396392 0.0718092 0.02876 +549 -0.0158083 -0.0164708 0.00645267 +550 0.016879 0.0245859 0.0055459 +551 -0.06884990000000001 0.0811361 0.0461884 +552 0.0290982 -0.00647478 0.008279069999999999 +553 -0.041817 0.0761358 0.0343691 +554 -0.0642688 0.0653922 0.00517065 +555 -0.0162175 0.00239503 0.00694561 +556 0.00467524 0.0360758 0.00643588 +557 -0.0222973 0.0035638 0.00646752 +558 -0.0708092 0.0801688 0.0482801 +559 -0.0549524 0.07870829999999999 0.0296023 +560 -0.06310540000000001 0.0672415 0.00811831 +561 -0.0155444 -0.0163359 0.0060847 +562 -0.0574097 0.07880470000000001 0.0473507 +563 -0.0558952 0.0591814 0.001764 +564 -0.0177409 0.0619627 0.0144786 +565 -0.00178349 -0.0487397 0.0125937 +566 -0.0111058 0.0522074 0.008299040000000001 +567 -0.0260139 0.00360897 0.00461987 +568 -0.0204566 0.00423454 0.00564674 +569 0.00612936 0.0370467 0.00680554 +570 0.010446 0.0313554 0.00705031 +571 -0.0569353 0.05965 0.00118235 +572 -0.0506685 0.0625792 0.00279292 +573 -0.0249761 0.00485573 0.00443819 +574 0.0172421 0.00725128 0.07382619999999999 +575 -0.0219613 0.06430039999999999 0.0138184 +576 -0.00260185 -0.0513557 0.0142694 +577 -0.0167422 0.00259292 0.00779623 +578 0.00214524 0.0341103 0.00650831 +579 -0.0236765 0.00572293 0.004305 +580 -0.0616879 0.0784644 0.0353636 +581 -0.0125522 0.0533024 0.00573952 +582 -0.00373263 -0.048886 0.014509 +583 -0.00253347 -0.0472982 0.0131992 +584 -0.0128746 -0.017623 0.00940414 +585 -5.43548e-05 0.0393803 0.00728201 +586 -0.0258702 0.00405717 0.00525282 +587 0.0183599 0.0265636 0.00640112 +588 0.0459896 -0.0257989 0.0100883 +589 -0.0295424 0.06805940000000001 0.0247957 +590 -0.0245383 0.0634107 0.0123732 +591 0.0066096 0.0377811 0.00691952 +592 -0.0450015 0.0646553 0.00575343 +593 -0.0622505 0.0661482 0.00839783 +594 -0.0256248 0.0608105 0.0161665 +595 0.017488 0.00853314 0.07209649999999999 +596 -0.0596734 0.07050969999999999 0.009924850000000001 +597 -0.06657979999999999 0.06286890000000001 0.00493615 +598 -0.0624322 0.0664941 0.0080812 +599 0.0436037 -0.00911409 0.009504510000000001 +600 -0.0258241 0.00183578 0.00455937 +601 -0.07027029999999999 0.07969130000000001 0.0546337 +602 -0.027947 0.06304949999999999 0.0231884 +603 -0.0601839 0.07046330000000001 0.0106076 +604 -0.019796 -0.0130118 0.0069497 +605 -0.0183149 0.06305479999999999 0.012418 +606 -0.0302535 0.0701272 0.02364 +607 -0.0574291 0.07908510000000001 0.0314511 +608 -0.0506885 0.0650762 0.00396145 +609 -0.021101 0.0616869 0.0137094 +610 -0.0331684 0.0670427 0.023997 +611 0.0134393 0.00644533 0.00718965 +612 -0.0111807 -0.0194906 0.00818236 +613 -0.0255718 0.00304117 0.00332801 +614 -0.0126697 -0.015488 0.00653208 +615 -0.0247074 0.00660999 0.00551935 +616 0.0173416 0.0031807 0.0727906 +617 0.0172416 0.0236783 0.00588169 +618 0.0190309 0.0293428 0.00437137 +619 0.016715 0.00646681 0.0747173 +620 -0.0362286 0.072292 0.023504 +621 -0.0193589 -0.00042516 0.00470745 +622 -0.0218861 0.06436310000000001 0.0125137 +623 -0.0102557 0.0512168 0.00711881 +624 0.0404202 -0.00631757 0.0116411 +625 0.0462272 -0.00679819 0.0101561 +626 -0.0259792 0.0656558 0.0150971 +627 0.0162732 0.0229634 0.00624384 +628 0.00353474 0.0364474 0.008433390000000001 +629 4.6368e-06 0.0388726 0.009730829999999999 +630 -0.0216501 0.0633078 0.012475 +631 -0.06535530000000001 0.0635995 0.0060088 +632 -0.0129397 0.0533345 0.00604151 +633 -0.00189413 -0.0244631 0.013557 +634 -0.0610974 0.0673557 0.00916116 +635 0.0169636 0.00823874 0.0726305 +636 -0.0262169 0.00566462 0.00486021 +637 -0.00105663 -0.050339 0.013034 +638 -0.0522352 0.0618469 0.00239028 +639 -0.06586110000000001 0.0623674 0.00600767 +640 -0.0308719 0.0671807 0.0240148 +641 -0.0271033 0.0631674 0.0232081 +642 0.000463176 0.0377435 0.00713404 +643 0.0197653 -0.0105149 0.0573133 +644 -0.0261272 0.00574879 0.00514751 +645 -0.0256133 0.00236555 0.00535812 +646 0.0395658 -0.00664927 0.0115095 +647 -0.0346515 0.0704144 0.0260764 +648 -0.0676857 0.0619198 0.00410476 +649 -0.0352382 0.07226829999999999 0.0261851 +650 -0.0489272 0.0632235 0.00329626 +651 -0.0514659 0.0617489 0.00295197 +652 -0.070483 0.0805389 0.0464472 +$EndNodes +$Elements +1654 +1 4 2 0 0 26 15 543 25 +2 4 2 0 0 227 308 190 188 +3 4 2 0 0 203 353 199 163 +4 4 2 0 0 331 305 504 150 +5 4 2 0 0 142 328 128 138 +6 4 2 0 0 490 439 18 571 +7 4 2 0 0 364 289 287 414 +8 4 2 0 0 296 336 304 298 +9 4 2 0 0 564 419 300 381 +10 4 2 0 0 398 569 373 591 +11 4 2 0 0 486 473 639 422 +12 4 2 0 0 338 89 566 489 +13 4 2 0 0 332 554 543 424 +14 4 2 0 0 80 67 71 302 +15 4 2 0 0 149 146 109 108 +16 4 2 0 0 98 90 375 342 +17 4 2 0 0 341 308 325 313 +18 4 2 0 0 147 314 126 116 +19 4 2 0 0 124 318 156 131 +20 4 2 0 0 245 322 206 308 +21 4 2 0 0 348 311 516 186 +22 4 2 0 0 135 150 319 151 +23 4 2 0 0 147 314 307 311 +24 4 2 0 0 464 588 301 528 +25 4 2 0 0 461 33 35 333 +26 4 2 0 0 196 192 373 314 +27 4 2 0 0 108 81 302 122 +28 4 2 0 0 366 258 227 357 +29 4 2 0 0 511 107 512 353 +30 4 2 0 0 146 170 354 172 +31 4 2 0 0 297 175 156 130 +32 4 2 0 0 130 297 175 308 +33 4 2 0 0 318 159 319 195 +34 4 2 0 0 154 123 122 342 +35 4 2 0 0 261 308 259 260 +36 4 2 0 0 132 142 128 318 +37 4 2 0 0 241 250 240 205 +38 4 2 0 0 226 227 248 324 +39 4 2 0 0 575 609 475 49 +40 4 2 0 0 375 91 123 90 +41 4 2 0 0 260 308 255 251 +42 4 2 0 0 517 612 63 482 +43 4 2 0 0 120 117 131 297 +44 4 2 0 0 318 131 297 156 +45 4 2 0 0 147 319 311 307 +46 4 2 0 0 131 120 297 130 +47 4 2 0 0 120 297 111 117 +48 4 2 0 0 308 174 206 360 +49 4 2 0 0 148 313 325 175 +50 4 2 0 0 148 313 175 174 +51 4 2 0 0 302 80 122 81 +52 4 2 0 0 107 353 511 110 +53 4 2 0 0 322 231 198 197 +54 4 2 0 0 61 58 564 57 +55 4 2 0 0 240 386 212 221 +56 4 2 0 0 121 297 143 117 +57 4 2 0 0 121 297 117 111 +58 4 2 0 0 307 235 314 182 +59 4 2 0 0 307 314 166 182 +60 4 2 0 0 417 308 175 316 +61 4 2 0 0 308 175 360 417 +62 4 2 0 0 601 9 458 1 +63 4 2 0 0 459 429 536 599 +64 4 2 0 0 211 242 206 308 +65 4 2 0 0 528 588 301 356 +66 4 2 0 0 316 297 308 175 +67 4 2 0 0 197 188 308 228 +68 4 2 0 0 231 308 228 197 +69 4 2 0 0 231 197 322 308 +70 4 2 0 0 188 197 308 361 +71 4 2 0 0 322 361 308 197 +72 4 2 0 0 259 308 256 255 +73 4 2 0 0 298 306 304 299 +74 4 2 0 0 302 342 146 122 +75 4 2 0 0 251 322 245 308 +76 4 2 0 0 298 306 299 236 +77 4 2 0 0 342 302 169 129 +78 4 2 0 0 157 319 331 150 +79 4 2 0 0 190 195 324 227 +80 4 2 0 0 146 342 354 154 +81 4 2 0 0 190 297 308 324 +82 4 2 0 0 236 254 306 299 +83 4 2 0 0 354 179 201 322 +84 4 2 0 0 308 297 188 361 +85 4 2 0 0 361 188 164 297 +86 4 2 0 0 195 165 190 318 +87 4 2 0 0 307 215 257 235 +88 4 2 0 0 194 235 215 307 +89 4 2 0 0 174 129 148 313 +90 4 2 0 0 169 313 129 174 +91 4 2 0 0 322 255 251 201 +92 4 2 0 0 366 265 308 258 +93 4 2 0 0 227 308 258 366 +94 4 2 0 0 258 308 249 265 +95 4 2 0 0 227 308 228 258 +96 4 2 0 0 448 192 373 196 +97 4 2 0 0 228 308 249 258 +98 4 2 0 0 296 298 514 336 +99 4 2 0 0 125 150 348 126 +100 4 2 0 0 125 160 348 150 +101 4 2 0 0 244 264 242 316 +102 4 2 0 0 264 316 244 271 +103 4 2 0 0 224 233 225 219 +104 4 2 0 0 107 353 163 199 +105 4 2 0 0 217 223 219 225 +106 4 2 0 0 308 174 313 206 +107 4 2 0 0 206 313 179 174 +108 4 2 0 0 241 230 212 233 +109 4 2 0 0 241 233 212 218 +110 4 2 0 0 267 278 312 273 +111 4 2 0 0 267 312 262 273 +112 4 2 0 0 206 179 322 245 +113 4 2 0 0 242 245 206 308 +114 4 2 0 0 144 319 159 157 +115 4 2 0 0 265 308 266 272 +116 4 2 0 0 218 219 392 233 +117 4 2 0 0 264 324 316 271 +118 4 2 0 0 324 308 264 316 +119 4 2 0 0 297 318 117 131 +120 4 2 0 0 128 117 318 124 +121 4 2 0 0 354 207 201 177 +122 4 2 0 0 207 177 354 184 +123 4 2 0 0 155 163 353 203 +124 4 2 0 0 131 297 156 130 +125 4 2 0 0 395 330 236 202 +126 4 2 0 0 164 142 318 190 +127 4 2 0 0 253 314 234 311 +128 4 2 0 0 307 314 147 166 +129 4 2 0 0 331 234 253 254 +130 4 2 0 0 306 236 298 331 +131 4 2 0 0 156 297 316 175 +132 4 2 0 0 324 319 318 316 +133 4 2 0 0 297 324 316 308 +134 4 2 0 0 373 314 102 125 +135 4 2 0 0 167 155 378 192 +136 4 2 0 0 278 324 272 269 +137 4 2 0 0 278 276 272 324 +138 4 2 0 0 319 159 157 336 +139 4 2 0 0 267 257 312 243 +140 4 2 0 0 307 215 243 257 +141 4 2 0 0 156 297 318 316 +142 4 2 0 0 207 354 170 184 +143 4 2 0 0 124 144 139 156 +144 4 2 0 0 267 312 250 243 +145 4 2 0 0 144 151 139 319 +146 4 2 0 0 318 316 319 144 +147 4 2 0 0 316 139 319 144 +148 4 2 0 0 139 144 316 156 +149 4 2 0 0 316 191 312 319 +150 4 2 0 0 316 191 317 156 +151 4 2 0 0 313 308 175 174 +152 4 2 0 0 253 234 331 311 +153 4 2 0 0 331 395 234 236 +154 4 2 0 0 272 265 308 366 +155 4 2 0 0 103 140 133 510 +156 4 2 0 0 235 199 246 314 +157 4 2 0 0 246 237 314 199 +158 4 2 0 0 144 151 319 157 +159 4 2 0 0 92 157 151 144 +160 4 2 0 0 92 159 157 144 +161 4 2 0 0 395 234 236 330 +162 4 2 0 0 395 330 202 348 +163 4 2 0 0 348 330 202 209 +164 4 2 0 0 324 312 316 271 +165 4 2 0 0 266 308 324 272 +166 4 2 0 0 324 366 308 227 +167 4 2 0 0 242 264 245 308 +168 4 2 0 0 272 266 269 324 +169 4 2 0 0 135 151 319 139 +170 4 2 0 0 40 35 28 29 +171 4 2 0 0 88 148 129 342 +172 4 2 0 0 325 342 148 88 +173 4 2 0 0 314 116 147 166 +174 4 2 0 0 77 353 320 94 +175 4 2 0 0 331 262 319 306 +176 4 2 0 0 319 317 139 316 +177 4 2 0 0 450 329 482 328 +178 4 2 0 0 183 307 147 166 +179 4 2 0 0 188 361 176 197 +180 4 2 0 0 169 179 313 174 +181 4 2 0 0 314 196 348 373 +182 4 2 0 0 102 84 116 353 +183 4 2 0 0 102 77 84 353 +184 4 2 0 0 191 147 319 317 +185 4 2 0 0 307 262 257 312 +186 4 2 0 0 307 257 246 235 +187 4 2 0 0 307 257 262 246 +188 4 2 0 0 128 318 144 124 +189 4 2 0 0 246 314 237 253 +190 4 2 0 0 314 203 237 234 +191 4 2 0 0 142 128 318 138 +192 4 2 0 0 253 237 234 314 +193 4 2 0 0 306 319 331 336 +194 4 2 0 0 307 314 235 246 +195 4 2 0 0 316 250 312 191 +196 4 2 0 0 450 403 349 329 +197 4 2 0 0 121 297 101 143 +198 4 2 0 0 382 164 101 297 +199 4 2 0 0 369 198 322 193 +200 4 2 0 0 264 266 324 269 +201 4 2 0 0 322 354 170 207 +202 4 2 0 0 322 170 193 207 +203 4 2 0 0 353 84 116 110 +204 4 2 0 0 70 302 68 83 +205 4 2 0 0 331 311 234 395 +206 4 2 0 0 323 493 282 301 +207 4 2 0 0 269 278 324 271 +208 4 2 0 0 278 312 324 271 +209 4 2 0 0 207 170 180 184 +210 4 2 0 0 207 170 193 180 +211 4 2 0 0 325 130 175 308 +212 4 2 0 0 146 354 170 154 +213 4 2 0 0 354 302 342 146 +214 4 2 0 0 161 348 510 181 +215 4 2 0 0 182 314 199 235 +216 4 2 0 0 322 354 369 170 +217 4 2 0 0 231 207 322 198 +218 4 2 0 0 313 322 375 341 +219 4 2 0 0 375 361 341 322 +220 4 2 0 0 322 207 193 198 +221 4 2 0 0 297 143 164 101 +222 4 2 0 0 221 213 240 232 +223 4 2 0 0 190 188 308 297 +224 4 2 0 0 341 361 375 382 +225 4 2 0 0 341 308 313 322 +226 4 2 0 0 134 158 184 354 +227 4 2 0 0 247 308 261 249 +228 4 2 0 0 263 308 260 251 +229 4 2 0 0 318 319 159 144 +230 4 2 0 0 309 262 306 319 +231 4 2 0 0 250 204 243 312 +232 4 2 0 0 448 192 167 378 +233 4 2 0 0 37 333 620 35 +234 4 2 0 0 37 33 333 35 +235 4 2 0 0 297 318 316 324 +236 4 2 0 0 167 448 378 153 +237 4 2 0 0 212 218 233 219 +238 4 2 0 0 88 325 342 494 +239 4 2 0 0 246 307 314 253 +240 4 2 0 0 307 253 246 262 +241 4 2 0 0 126 311 150 348 +242 4 2 0 0 388 611 336 514 +243 4 2 0 0 348 234 420 314 +244 4 2 0 0 236 254 331 306 +245 4 2 0 0 348 314 311 234 +246 4 2 0 0 211 308 360 417 +247 4 2 0 0 373 102 320 125 +248 4 2 0 0 316 250 191 438 +249 4 2 0 0 250 205 191 438 +250 4 2 0 0 254 262 306 309 +251 4 2 0 0 254 309 306 310 +252 4 2 0 0 299 254 306 310 +253 4 2 0 0 331 262 306 254 +254 4 2 0 0 292 294 295 293 +255 4 2 0 0 194 307 215 204 +256 4 2 0 0 304 306 384 299 +257 4 2 0 0 267 312 257 262 +258 4 2 0 0 353 192 378 155 +259 4 2 0 0 319 159 336 195 +260 4 2 0 0 353 192 373 378 +261 4 2 0 0 336 185 388 195 +262 4 2 0 0 312 250 271 267 +263 4 2 0 0 271 250 312 316 +264 4 2 0 0 261 249 308 265 +265 4 2 0 0 268 308 265 261 +266 4 2 0 0 247 308 249 228 +267 4 2 0 0 227 195 324 226 +268 4 2 0 0 366 324 415 337 +269 4 2 0 0 337 366 324 357 +270 4 2 0 0 190 195 318 324 +271 4 2 0 0 156 318 124 144 +272 4 2 0 0 263 266 308 264 +273 4 2 0 0 251 263 308 264 +274 4 2 0 0 197 198 322 369 +275 4 2 0 0 154 354 369 342 +276 4 2 0 0 188 308 228 227 +277 4 2 0 0 79 328 138 92 +278 4 2 0 0 316 317 139 156 +279 4 2 0 0 360 175 308 174 +280 4 2 0 0 255 251 308 322 +281 4 2 0 0 255 256 252 308 +282 4 2 0 0 247 228 231 308 +283 4 2 0 0 247 308 231 256 +284 4 2 0 0 134 149 394 354 +285 4 2 0 0 83 162 96 302 +286 4 2 0 0 161 373 140 348 +287 4 2 0 0 88 67 302 68 +288 4 2 0 0 302 97 88 68 +289 4 2 0 0 512 166 314 182 +290 4 2 0 0 420 192 314 234 +291 4 2 0 0 348 330 420 234 +292 4 2 0 0 192 314 234 203 +293 4 2 0 0 91 123 105 115 +294 4 2 0 0 394 70 302 81 +295 4 2 0 0 309 273 262 319 +296 4 2 0 0 319 262 312 273 +297 4 2 0 0 67 302 68 70 +298 4 2 0 0 271 278 312 267 +299 4 2 0 0 66 57 326 58 +300 4 2 0 0 188 136 176 361 +301 4 2 0 0 157 331 185 504 +302 4 2 0 0 136 361 188 164 +303 4 2 0 0 244 250 271 316 +304 4 2 0 0 71 302 67 70 +305 4 2 0 0 244 213 232 240 +306 4 2 0 0 81 302 71 70 +307 4 2 0 0 354 149 108 146 +308 4 2 0 0 314 237 203 199 +309 4 2 0 0 506 378 435 629 +310 4 2 0 0 244 438 316 213 +311 4 2 0 0 97 302 169 162 +312 4 2 0 0 244 316 438 250 +313 4 2 0 0 313 129 342 169 +314 4 2 0 0 382 113 101 164 +315 4 2 0 0 506 435 378 94 +316 4 2 0 0 91 123 85 105 +317 4 2 0 0 308 264 245 251 +318 4 2 0 0 242 264 308 316 +319 4 2 0 0 450 349 482 329 +320 4 2 0 0 314 373 348 125 +321 4 2 0 0 92 138 159 144 +322 4 2 0 0 395 311 234 348 +323 4 2 0 0 278 273 324 312 +324 4 2 0 0 373 378 435 320 +325 4 2 0 0 147 311 319 135 +326 4 2 0 0 126 311 135 150 +327 4 2 0 0 126 135 311 147 +328 4 2 0 0 314 348 311 126 +329 4 2 0 0 83 302 82 70 +330 4 2 0 0 378 435 629 373 +331 4 2 0 0 195 159 165 318 +332 4 2 0 0 316 312 324 319 +333 4 2 0 0 156 175 316 387 +334 4 2 0 0 336 298 514 331 +335 4 2 0 0 88 342 129 302 +336 4 2 0 0 319 307 331 311 +337 4 2 0 0 253 314 311 307 +338 4 2 0 0 311 331 253 307 +339 4 2 0 0 297 341 308 130 +340 4 2 0 0 314 348 126 125 +341 4 2 0 0 147 314 311 126 +342 4 2 0 0 61 339 99 338 +343 4 2 0 0 250 204 312 191 +344 4 2 0 0 305 185 508 331 +345 4 2 0 0 211 242 308 316 +346 4 2 0 0 211 308 417 316 +347 4 2 0 0 213 316 211 417 +348 4 2 0 0 214 215 230 204 +349 4 2 0 0 244 316 242 211 +350 4 2 0 0 244 211 213 316 +351 4 2 0 0 465 501 344 502 +352 4 2 0 0 108 354 302 394 +353 4 2 0 0 313 129 148 342 +354 4 2 0 0 337 324 415 248 +355 4 2 0 0 337 258 366 357 +356 4 2 0 0 121 101 297 111 +357 4 2 0 0 382 101 111 297 +358 4 2 0 0 157 159 185 336 +359 4 2 0 0 226 336 195 324 +360 4 2 0 0 307 262 331 253 +361 4 2 0 0 307 262 319 331 +362 4 2 0 0 331 254 253 262 +363 4 2 0 0 248 336 552 296 +364 4 2 0 0 319 324 195 336 +365 4 2 0 0 248 296 226 336 +366 4 2 0 0 324 248 336 552 +367 4 2 0 0 147 183 191 307 +368 4 2 0 0 282 281 276 323 +369 4 2 0 0 281 323 282 301 +370 4 2 0 0 109 119 105 122 +371 4 2 0 0 297 143 117 318 +372 4 2 0 0 109 122 105 80 +373 4 2 0 0 308 366 324 272 +374 4 2 0 0 297 318 324 190 +375 4 2 0 0 297 190 164 318 +376 4 2 0 0 214 204 230 212 +377 4 2 0 0 224 212 214 230 +378 4 2 0 0 297 143 318 164 +379 4 2 0 0 264 308 324 266 +380 4 2 0 0 264 269 324 271 +381 4 2 0 0 132 117 143 318 +382 4 2 0 0 130 297 341 120 +383 4 2 0 0 341 130 120 98 +384 4 2 0 0 277 343 356 279 +385 4 2 0 0 325 308 175 313 +386 4 2 0 0 109 81 108 122 +387 4 2 0 0 109 122 108 146 +388 4 2 0 0 348 234 395 330 +389 4 2 0 0 341 111 120 297 +390 4 2 0 0 341 100 98 120 +391 4 2 0 0 341 111 100 120 +392 4 2 0 0 226 336 324 248 +393 4 2 0 0 318 319 324 195 +394 4 2 0 0 275 270 324 309 +395 4 2 0 0 309 336 324 319 +396 4 2 0 0 552 270 336 324 +397 4 2 0 0 273 309 275 324 +398 4 2 0 0 403 328 329 450 +399 4 2 0 0 382 111 341 297 +400 4 2 0 0 361 322 308 341 +401 4 2 0 0 361 341 308 297 +402 4 2 0 0 342 85 73 90 +403 4 2 0 0 342 73 85 80 +404 4 2 0 0 323 324 366 276 +405 4 2 0 0 361 297 164 382 +406 4 2 0 0 96 82 83 302 +407 4 2 0 0 45 647 44 42 +408 4 2 0 0 179 354 201 177 +409 4 2 0 0 53 621 54 347 +410 4 2 0 0 117 124 131 318 +411 4 2 0 0 156 144 316 318 +412 4 2 0 0 369 198 193 141 +413 4 2 0 0 342 302 88 67 +414 4 2 0 0 67 80 342 302 +415 4 2 0 0 73 80 342 67 +416 4 2 0 0 342 73 67 76 +417 4 2 0 0 372 528 289 285 +418 4 2 0 0 285 528 289 287 +419 4 2 0 0 355 98 325 494 +420 4 2 0 0 122 119 105 123 +421 4 2 0 0 394 82 134 302 +422 4 2 0 0 494 88 76 342 +423 4 2 0 0 109 81 122 80 +424 4 2 0 0 447 580 503 505 +425 4 2 0 0 114 118 141 145 +426 4 2 0 0 311 150 319 135 +427 4 2 0 0 108 122 302 146 +428 4 2 0 0 204 307 183 194 +429 4 2 0 0 191 204 307 183 +430 4 2 0 0 382 101 100 111 +431 4 2 0 0 382 111 100 341 +432 4 2 0 0 318 159 138 144 +433 4 2 0 0 588 281 301 356 +434 4 2 0 0 87 61 77 57 +435 4 2 0 0 318 159 165 138 +436 4 2 0 0 7 12 2 486 +437 4 2 0 0 316 191 319 317 +438 4 2 0 0 208 196 449 445 +439 4 2 0 0 322 369 354 313 +440 4 2 0 0 354 158 177 162 +441 4 2 0 0 354 169 162 179 +442 4 2 0 0 313 369 354 342 +443 4 2 0 0 179 162 354 177 +444 4 2 0 0 130 98 341 355 +445 4 2 0 0 325 130 341 355 +446 4 2 0 0 337 357 324 248 +447 4 2 0 0 324 357 227 248 +448 4 2 0 0 588 281 464 301 +449 4 2 0 0 375 341 382 98 +450 4 2 0 0 454 75 61 155 +451 4 2 0 0 353 77 84 74 +452 4 2 0 0 331 305 185 504 +453 4 2 0 0 311 331 319 150 +454 4 2 0 0 378 339 167 106 +455 4 2 0 0 318 190 142 165 +456 4 2 0 0 138 142 165 318 +457 4 2 0 0 18 12 397 14 +458 4 2 0 0 298 514 331 513 +459 4 2 0 0 118 137 141 168 +460 4 2 0 0 298 331 236 395 +461 4 2 0 0 395 298 331 513 +462 4 2 0 0 93 157 92 159 +463 4 2 0 0 354 158 184 177 +464 4 2 0 0 151 157 92 93 +465 4 2 0 0 78 93 151 92 +466 4 2 0 0 378 448 629 153 +467 4 2 0 0 102 314 126 125 +468 4 2 0 0 126 116 314 102 +469 4 2 0 0 61 72 303 75 +470 4 2 0 0 39 461 350 553 +471 4 2 0 0 350 39 33 461 +472 4 2 0 0 311 331 513 395 +473 4 2 0 0 311 331 305 509 +474 4 2 0 0 353 102 314 116 +475 4 2 0 0 204 215 243 307 +476 4 2 0 0 106 153 167 378 +477 4 2 0 0 97 162 83 302 +478 4 2 0 0 107 353 199 512 +479 4 2 0 0 297 188 164 190 +480 4 2 0 0 147 319 139 135 +481 4 2 0 0 77 353 87 74 +482 4 2 0 0 353 203 199 314 +483 4 2 0 0 512 314 353 199 +484 4 2 0 0 37 38 29 35 +485 4 2 0 0 485 140 373 125 +486 4 2 0 0 398 448 373 196 +487 4 2 0 0 196 570 373 398 +488 4 2 0 0 324 248 552 415 +489 4 2 0 0 415 270 552 324 +490 4 2 0 0 52 57 594 564 +491 4 2 0 0 285 289 414 287 +492 4 2 0 0 438 250 205 240 +493 4 2 0 0 524 425 25 17 +494 4 2 0 0 29 25 524 425 +495 4 2 0 0 87 77 61 353 +496 4 2 0 0 93 92 138 159 +497 4 2 0 0 93 92 79 138 +498 4 2 0 0 203 192 353 155 +499 4 2 0 0 192 353 314 203 +500 4 2 0 0 88 302 129 97 +501 4 2 0 0 169 342 354 302 +502 4 2 0 0 147 319 317 139 +503 4 2 0 0 435 426 629 373 +504 4 2 0 0 197 168 369 176 +505 4 2 0 0 369 176 361 197 +506 4 2 0 0 157 151 319 150 +507 4 2 0 0 307 319 312 191 +508 4 2 0 0 312 307 191 204 +509 4 2 0 0 628 373 441 374 +510 4 2 0 0 513 331 311 509 +511 4 2 0 0 49 594 413 46 +512 4 2 0 0 303 163 87 61 +513 4 2 0 0 146 342 154 122 +514 4 2 0 0 274 366 415 337 +515 4 2 0 0 274 258 366 337 +516 4 2 0 0 87 57 74 66 +517 4 2 0 0 304 306 336 384 +518 4 2 0 0 204 250 205 191 +519 4 2 0 0 110 74 66 87 +520 4 2 0 0 163 87 61 353 +521 4 2 0 0 204 205 250 241 +522 4 2 0 0 387 438 213 316 +523 4 2 0 0 150 160 348 311 +524 4 2 0 0 313 369 342 375 +525 4 2 0 0 313 322 369 375 +526 4 2 0 0 97 129 169 302 +527 4 2 0 0 504 305 393 150 +528 4 2 0 0 181 348 500 187 +529 4 2 0 0 610 527 42 44 +530 4 2 0 0 44 527 42 620 +531 4 2 0 0 311 305 456 509 +532 4 2 0 0 311 509 456 516 +533 4 2 0 0 365 512 166 116 +534 4 2 0 0 116 512 166 314 +535 4 2 0 0 509 305 508 331 +536 4 2 0 0 322 369 193 170 +537 4 2 0 0 535 526 581 632 +538 4 2 0 0 182 314 512 199 +539 4 2 0 0 497 441 373 540 +540 4 2 0 0 37 42 46 527 +541 4 2 0 0 500 209 187 348 +542 4 2 0 0 312 257 307 243 +543 4 2 0 0 323 366 281 276 +544 4 2 0 0 348 420 209 196 +545 4 2 0 0 366 279 276 272 +546 4 2 0 0 202 500 186 348 +547 4 2 0 0 386 406 221 232 +548 4 2 0 0 64 526 62 489 +549 4 2 0 0 336 159 185 195 +550 4 2 0 0 404 24 559 335 +551 4 2 0 0 404 24 607 559 +552 4 2 0 0 384 336 552 270 +553 4 2 0 0 244 240 438 213 +554 4 2 0 0 244 438 240 250 +555 4 2 0 0 430 461 620 333 +556 4 2 0 0 461 333 35 620 +557 4 2 0 0 61 564 64 334 +558 4 2 0 0 381 437 47 413 +559 4 2 0 0 279 277 265 258 +560 4 2 0 0 279 277 258 274 +561 4 2 0 0 186 500 181 348 +562 4 2 0 0 140 510 348 160 +563 4 2 0 0 377 410 36 350 +564 4 2 0 0 202 330 236 209 +565 4 2 0 0 380 345 614 468 +566 4 2 0 0 99 339 378 106 +567 4 2 0 0 378 106 418 99 +568 4 2 0 0 378 448 373 629 +569 4 2 0 0 194 235 307 182 +570 4 2 0 0 194 307 166 182 +571 4 2 0 0 194 307 183 166 +572 4 2 0 0 353 373 320 378 +573 4 2 0 0 68 97 83 302 +574 4 2 0 0 347 496 604 476 +575 4 2 0 0 161 181 411 373 +576 4 2 0 0 570 374 400 368 +577 4 2 0 0 40 38 35 29 +578 4 2 0 0 364 289 327 528 +579 4 2 0 0 324 309 319 273 +580 4 2 0 0 353 378 320 94 +581 4 2 0 0 358 91 471 375 +582 4 2 0 0 134 394 302 354 +583 4 2 0 0 394 149 108 354 +584 4 2 0 0 172 354 146 149 +585 4 2 0 0 382 358 471 375 +586 4 2 0 0 101 382 90 358 +587 4 2 0 0 651 346 638 390 +588 4 2 0 0 382 90 100 101 +589 4 2 0 0 334 594 564 475 +590 4 2 0 0 369 361 375 322 +591 4 2 0 0 322 197 369 361 +592 4 2 0 0 342 325 98 494 +593 4 2 0 0 325 313 148 342 +594 4 2 0 0 342 325 375 98 +595 4 2 0 0 115 369 123 367 +596 4 2 0 0 342 98 76 494 +597 4 2 0 0 369 375 576 115 +598 4 2 0 0 353 512 116 314 +599 4 2 0 0 336 304 552 296 +600 4 2 0 0 336 306 304 298 +601 4 2 0 0 226 514 336 296 +602 4 2 0 0 108 302 81 394 +603 4 2 0 0 181 411 373 374 +604 4 2 0 0 26 440 571 383 +605 4 2 0 0 26 383 346 440 +606 4 2 0 0 211 360 308 206 +607 4 2 0 0 87 74 57 77 +608 4 2 0 0 358 113 101 382 +609 4 2 0 0 195 388 336 226 +610 4 2 0 0 241 233 218 238 +611 4 2 0 0 155 339 378 353 +612 4 2 0 0 345 79 468 476 +613 4 2 0 0 213 316 417 175 +614 4 2 0 0 387 316 213 175 +615 4 2 0 0 312 307 262 319 +616 4 2 0 0 435 485 426 373 +617 4 2 0 0 435 373 125 485 +618 4 2 0 0 299 310 306 384 +619 4 2 0 0 26 425 25 34 +620 4 2 0 0 118 114 367 434 +621 4 2 0 0 26 34 25 608 +622 4 2 0 0 223 222 529 392 +623 4 2 0 0 527 38 37 35 +624 4 2 0 0 37 527 46 38 +625 4 2 0 0 342 123 90 375 +626 4 2 0 0 342 123 85 90 +627 4 2 0 0 335 350 33 35 +628 4 2 0 0 350 461 33 35 +629 4 2 0 0 85 91 90 123 +630 4 2 0 0 259 247 308 261 +631 4 2 0 0 629 628 448 373 +632 4 2 0 0 633 142 328 128 +633 4 2 0 0 629 497 628 373 +634 4 2 0 0 303 61 87 72 +635 4 2 0 0 236 254 234 331 +636 4 2 0 0 341 98 325 355 +637 4 2 0 0 373 570 400 569 +638 4 2 0 0 398 570 373 569 +639 4 2 0 0 49 413 527 46 +640 4 2 0 0 49 46 527 457 +641 4 2 0 0 49 626 48 527 +642 4 2 0 0 241 204 243 250 +643 4 2 0 0 49 527 48 457 +644 4 2 0 0 392 218 233 238 +645 4 2 0 0 233 392 238 223 +646 4 2 0 0 178 198 197 141 +647 4 2 0 0 198 197 141 369 +648 4 2 0 0 364 290 287 528 +649 4 2 0 0 419 381 564 413 +650 4 2 0 0 92 78 79 59 +651 4 2 0 0 192 373 314 353 +652 4 2 0 0 386 406 238 423 +653 4 2 0 0 367 369 137 391 +654 4 2 0 0 437 413 419 606 +655 4 2 0 0 413 437 47 606 +656 4 2 0 0 239 252 322 255 +657 4 2 0 0 454 61 339 155 +658 4 2 0 0 34 466 425 29 +659 4 2 0 0 221 386 232 240 +660 4 2 0 0 60 64 489 484 +661 4 2 0 0 484 65 60 64 +662 4 2 0 0 212 386 218 221 +663 4 2 0 0 241 240 386 212 +664 4 2 0 0 241 205 240 212 +665 4 2 0 0 607 24 16 470 +666 4 2 0 0 620 42 37 527 +667 4 2 0 0 37 333 42 620 +668 4 2 0 0 95 87 66 69 +669 4 2 0 0 113 164 382 361 +670 4 2 0 0 410 30 432 21 +671 4 2 0 0 371 1 522 458 +672 4 2 0 0 527 47 43 40 +673 4 2 0 0 596 425 17 15 +674 4 2 0 0 393 456 160 311 +675 4 2 0 0 110 95 87 66 +676 4 2 0 0 160 311 456 516 +677 4 2 0 0 512 511 365 166 +678 4 2 0 0 353 511 365 512 +679 4 2 0 0 128 144 318 138 +680 4 2 0 0 341 130 325 308 +681 4 2 0 0 87 61 57 58 +682 4 2 0 0 419 58 564 72 +683 4 2 0 0 414 289 327 364 +684 4 2 0 0 320 378 435 94 +685 4 2 0 0 364 528 287 289 +686 4 2 0 0 212 221 205 240 +687 4 2 0 0 134 172 149 354 +688 4 2 0 0 134 172 354 184 +689 4 2 0 0 319 147 191 307 +690 4 2 0 0 589 641 606 436 +691 4 2 0 0 347 79 59 476 +692 4 2 0 0 345 79 476 92 +693 4 2 0 0 92 138 144 328 +694 4 2 0 0 86 92 144 328 +695 4 2 0 0 32 399 34 38 +696 4 2 0 0 306 309 336 310 +697 4 2 0 0 347 604 468 476 +698 4 2 0 0 347 468 79 476 +699 4 2 0 0 614 345 79 468 +700 4 2 0 0 384 310 336 270 +701 4 2 0 0 439 25 26 422 +702 4 2 0 0 196 192 314 420 +703 4 2 0 0 348 420 196 314 +704 4 2 0 0 132 143 142 318 +705 4 2 0 0 164 142 143 318 +706 4 2 0 0 386 406 423 221 +707 4 2 0 0 35 527 38 40 +708 4 2 0 0 158 354 96 162 +709 4 2 0 0 169 302 354 162 +710 4 2 0 0 334 475 564 363 +711 4 2 0 0 155 61 303 75 +712 4 2 0 0 94 353 378 339 +713 4 2 0 0 224 233 219 212 +714 4 2 0 0 214 215 204 194 +715 4 2 0 0 204 243 230 241 +716 4 2 0 0 204 230 212 241 +717 4 2 0 0 391 474 369 136 +718 4 2 0 0 286 588 528 356 +719 4 2 0 0 35 620 527 47 +720 4 2 0 0 136 474 361 565 +721 4 2 0 0 566 526 632 64 +722 4 2 0 0 490 439 11 14 +723 4 2 0 0 209 330 420 348 +724 4 2 0 0 35 527 40 47 +725 4 2 0 0 76 342 73 98 +726 4 2 0 0 77 353 102 320 +727 4 2 0 0 268 308 261 260 +728 4 2 0 0 167 155 339 378 +729 4 2 0 0 465 289 385 344 +730 4 2 0 0 255 308 260 259 +731 4 2 0 0 335 24 470 33 +732 4 2 0 0 559 24 470 335 +733 4 2 0 0 522 1 371 428 +734 4 2 0 0 347 53 496 54 +735 4 2 0 0 559 24 607 470 +736 4 2 0 0 476 347 496 54 +737 4 2 0 0 312 204 243 307 +738 4 2 0 0 230 215 243 204 +739 4 2 0 0 241 218 212 386 +740 4 2 0 0 241 238 218 386 +741 4 2 0 0 29 33 28 23 +742 4 2 0 0 23 335 559 470 +743 4 2 0 0 297 382 361 341 +744 4 2 0 0 336 611 185 331 +745 4 2 0 0 388 185 336 611 +746 4 2 0 0 353 373 102 320 +747 4 2 0 0 373 102 314 353 +748 4 2 0 0 44 527 606 610 +749 4 2 0 0 74 110 84 353 +750 4 2 0 0 610 527 606 413 +751 4 2 0 0 325 341 375 98 +752 4 2 0 0 369 136 137 391 +753 4 2 0 0 169 354 342 313 +754 4 2 0 0 274 366 279 281 +755 4 2 0 0 281 366 279 276 +756 4 2 0 0 322 313 206 308 +757 4 2 0 0 414 289 344 385 +758 4 2 0 0 114 546 367 434 +759 4 2 0 0 367 391 434 369 +760 4 2 0 0 155 163 303 61 +761 4 2 0 0 47 620 527 44 +762 4 2 0 0 384 304 552 336 +763 4 2 0 0 384 310 306 336 +764 4 2 0 0 99 378 339 94 +765 4 2 0 0 506 94 378 99 +766 4 2 0 0 365 353 512 116 +767 4 2 0 0 378 99 418 506 +768 4 2 0 0 478 23 559 470 +769 4 2 0 0 328 86 633 128 +770 4 2 0 0 265 308 268 266 +771 4 2 0 0 268 308 263 266 +772 4 2 0 0 564 419 436 58 +773 4 2 0 0 460 75 564 65 +774 4 2 0 0 339 61 99 94 +775 4 2 0 0 518 564 65 460 +776 4 2 0 0 643 216 229 392 +777 4 2 0 0 342 88 76 67 +778 4 2 0 0 26 422 11 439 +779 4 2 0 0 26 440 439 571 +780 4 2 0 0 411 161 373 441 +781 4 2 0 0 442 467 412 10 +782 4 2 0 0 350 377 24 33 +783 4 2 0 0 225 409 217 223 +784 4 2 0 0 410 377 24 350 +785 4 2 0 0 24 350 33 335 +786 4 2 0 0 371 522 523 458 +787 4 2 0 0 278 324 273 276 +788 4 2 0 0 273 324 275 276 +789 4 2 0 0 170 354 172 184 +790 4 2 0 0 169 179 354 313 +791 4 2 0 0 607 16 24 580 +792 4 2 0 0 367 391 137 118 +793 4 2 0 0 35 620 37 527 +794 4 2 0 0 548 33 461 333 +795 4 2 0 0 414 385 344 294 +796 4 2 0 0 414 289 288 344 +797 4 2 0 0 65 64 484 454 +798 4 2 0 0 93 79 78 401 +799 4 2 0 0 375 382 358 90 +800 4 2 0 0 413 575 564 594 +801 4 2 0 0 187 181 368 189 +802 4 2 0 0 358 375 90 91 +803 4 2 0 0 275 276 324 323 +804 4 2 0 0 493 270 323 275 +805 4 2 0 0 532 323 276 275 +806 4 2 0 0 324 270 323 415 +807 4 2 0 0 275 323 324 270 +808 4 2 0 0 157 331 319 336 +809 4 2 0 0 454 339 61 338 +810 4 2 0 0 527 47 507 43 +811 4 2 0 0 74 87 110 353 +812 4 2 0 0 61 353 339 155 +813 4 2 0 0 444 445 618 379 +814 4 2 0 0 173 133 160 510 +815 4 2 0 0 352 604 468 347 +816 4 2 0 0 161 181 373 348 +817 4 2 0 0 23 335 470 33 +818 4 2 0 0 181 187 374 373 +819 4 2 0 0 29 35 28 33 +820 4 2 0 0 348 187 181 373 +821 4 2 0 0 562 10 412 447 +822 4 2 0 0 10 580 503 447 +823 4 2 0 0 399 351 34 38 +824 4 2 0 0 515 592 399 32 +825 4 2 0 0 434 112 637 474 +826 4 2 0 0 134 82 96 302 +827 4 2 0 0 224 230 233 212 +828 4 2 0 0 134 302 96 354 +829 4 2 0 0 302 354 162 96 +830 4 2 0 0 376 64 60 564 +831 4 2 0 0 606 640 589 45 +832 4 2 0 0 369 137 168 141 +833 4 2 0 0 113 361 583 136 +834 4 2 0 0 197 369 168 141 +835 4 2 0 0 12 7 4 14 +836 4 2 0 0 510 181 173 171 +837 4 2 0 0 61 339 353 94 +838 4 2 0 0 369 154 170 354 +839 4 2 0 0 404 607 24 21 +840 4 2 0 0 411 374 578 441 +841 4 2 0 0 500 186 189 480 +842 4 2 0 0 535 526 632 566 +843 4 2 0 0 628 441 497 483 +844 4 2 0 0 478 23 28 559 +845 4 2 0 0 28 335 559 23 +846 4 2 0 0 93 92 78 79 +847 4 2 0 0 554 473 631 453 +848 4 2 0 0 198 178 193 141 +849 4 2 0 0 187 444 209 500 +850 4 2 0 0 226 388 336 514 +851 4 2 0 0 287 464 285 528 +852 4 2 0 0 528 301 285 372 +853 4 2 0 0 497 629 426 373 +854 4 2 0 0 394 302 70 82 +855 4 2 0 0 64 61 454 75 +856 4 2 0 0 444 587 618 445 +857 4 2 0 0 467 458 371 523 +858 4 2 0 0 371 523 520 467 +859 4 2 0 0 371 520 551 467 +860 4 2 0 0 385 465 294 292 +861 4 2 0 0 468 604 345 476 +862 4 2 0 0 584 517 63 345 +863 4 2 0 0 176 136 137 369 +864 4 2 0 0 439 440 18 571 +865 4 2 0 0 490 26 11 439 +866 4 2 0 0 324 366 227 357 +867 4 2 0 0 606 413 419 436 +868 4 2 0 0 527 48 477 507 +869 4 2 0 0 527 477 48 457 +870 4 2 0 0 527 492 48 507 +871 4 2 0 0 527 626 48 492 +872 4 2 0 0 134 354 96 158 +873 4 2 0 0 62 64 489 60 +874 4 2 0 0 52 57 370 594 +875 4 2 0 0 326 52 55 564 +876 4 2 0 0 524 425 17 19 +877 4 2 0 0 373 441 161 540 +878 4 2 0 0 373 161 140 540 +879 4 2 0 0 66 326 55 58 +880 4 2 0 0 58 326 55 564 +881 4 2 0 0 310 309 336 270 +882 4 2 0 0 324 270 336 309 +883 4 2 0 0 157 336 185 331 +884 4 2 0 0 181 411 171 161 +885 4 2 0 0 640 589 641 606 +886 4 2 0 0 537 557 621 54 +887 4 2 0 0 282 285 340 288 +888 4 2 0 0 372 285 288 340 +889 4 2 0 0 382 100 98 341 +890 4 2 0 0 502 294 465 292 +891 4 2 0 0 43 34 351 38 +892 4 2 0 0 221 240 213 205 +893 4 2 0 0 438 240 205 213 +894 4 2 0 0 425 466 524 29 +895 4 2 0 0 354 302 146 108 +896 4 2 0 0 435 426 506 629 +897 4 2 0 0 497 506 426 629 +898 4 2 0 0 187 181 374 368 +899 4 2 0 0 517 79 614 345 +900 4 2 0 0 342 90 73 98 +901 4 2 0 0 180 141 178 152 +902 4 2 0 0 178 152 141 168 +903 4 2 0 0 193 180 141 178 +904 4 2 0 0 140 161 348 510 +905 4 2 0 0 9 442 13 362 +906 4 2 0 0 442 9 13 467 +907 4 2 0 0 408 505 503 580 +908 4 2 0 0 607 580 408 16 +909 4 2 0 0 327 289 414 385 +910 4 2 0 0 372 284 283 340 +911 4 2 0 0 359 89 526 566 +912 4 2 0 0 607 539 478 470 +913 4 2 0 0 140 373 125 348 +914 4 2 0 0 328 86 92 517 +915 4 2 0 0 527 47 44 606 +916 4 2 0 0 155 163 61 353 +917 4 2 0 0 367 391 118 434 +918 4 2 0 0 338 64 61 454 +919 4 2 0 0 64 338 484 454 +920 4 2 0 0 359 89 566 338 +921 4 2 0 0 489 526 566 64 +922 4 2 0 0 448 192 378 373 +923 4 2 0 0 350 39 377 33 +924 4 2 0 0 369 137 176 168 +925 4 2 0 0 377 350 553 39 +926 4 2 0 0 325 313 375 341 +927 4 2 0 0 340 288 625 282 +928 4 2 0 0 342 313 375 325 +929 4 2 0 0 524 466 19 20 +930 4 2 0 0 425 466 19 524 +931 4 2 0 0 348 395 186 202 +932 4 2 0 0 610 44 42 45 +933 4 2 0 0 409 433 217 223 +934 4 2 0 0 217 433 529 223 +935 4 2 0 0 582 375 471 115 +936 4 2 0 0 434 474 637 369 +937 4 2 0 0 382 375 471 582 +938 4 2 0 0 98 90 382 375 +939 4 2 0 0 382 100 90 98 +940 4 2 0 0 123 105 122 85 +941 4 2 0 0 122 85 105 80 +942 4 2 0 0 43 40 34 38 +943 4 2 0 0 369 474 361 136 +944 4 2 0 0 469 452 564 460 +945 4 2 0 0 46 41 527 457 +946 4 2 0 0 415 366 274 323 +947 4 2 0 0 191 387 316 438 +948 4 2 0 0 191 387 156 316 +949 4 2 0 0 434 391 474 369 +950 4 2 0 0 502 294 344 465 +951 4 2 0 0 502 294 292 293 +952 4 2 0 0 476 59 92 79 +953 4 2 0 0 306 309 319 336 +954 4 2 0 0 528 301 464 285 +955 4 2 0 0 301 282 464 285 +956 4 2 0 0 208 449 210 379 +957 4 2 0 0 210 379 220 208 +958 4 2 0 0 551 520 10 467 +959 4 2 0 0 359 89 339 106 +960 4 2 0 0 110 353 365 116 +961 4 2 0 0 353 511 110 365 +962 4 2 0 0 118 141 145 152 +963 4 2 0 0 34 28 466 29 +964 4 2 0 0 621 347 59 54 +965 4 2 0 0 59 621 79 347 +966 4 2 0 0 342 80 122 302 +967 4 2 0 0 369 123 154 342 +968 4 2 0 0 123 85 122 342 +969 4 2 0 0 122 342 85 80 +970 4 2 0 0 450 349 612 482 +971 4 2 0 0 564 55 436 413 +972 4 2 0 0 40 38 29 34 +973 4 2 0 0 606 641 413 436 +974 4 2 0 0 28 35 335 33 +975 4 2 0 0 34 25 32 29 +976 4 2 0 0 487 548 495 479 +977 4 2 0 0 187 209 196 348 +978 4 2 0 0 461 479 430 495 +979 4 2 0 0 311 513 509 186 +980 4 2 0 0 395 311 348 186 +981 4 2 0 0 187 196 209 444 +982 4 2 0 0 485 540 426 373 +983 4 2 0 0 21 580 24 447 +984 4 2 0 0 412 447 21 562 +985 4 2 0 0 412 562 21 446 +986 4 2 0 0 447 580 24 10 +987 4 2 0 0 46 527 610 413 +988 4 2 0 0 229 392 216 222 +989 4 2 0 0 323 281 366 274 +990 4 2 0 0 281 301 274 323 +991 4 2 0 0 599 625 429 282 +992 4 2 0 0 608 25 32 34 +993 4 2 0 0 372 288 284 340 +994 4 2 0 0 227 324 190 308 +995 4 2 0 0 373 196 348 187 +996 4 2 0 0 425 25 34 29 +997 4 2 0 0 628 448 373 591 +998 4 2 0 0 591 448 373 398 +999 4 2 0 0 477 43 41 527 +1000 4 2 0 0 80 71 81 302 +1001 4 2 0 0 457 477 41 527 +1002 4 2 0 0 647 487 430 479 +1003 4 2 0 0 628 373 497 441 +1004 4 2 0 0 578 628 441 374 +1005 4 2 0 0 410 24 335 350 +1006 4 2 0 0 393 311 160 150 +1007 4 2 0 0 367 118 137 141 +1008 4 2 0 0 343 488 356 396 +1009 4 2 0 0 87 72 61 58 +1010 4 2 0 0 488 588 356 396 +1011 4 2 0 0 476 54 59 347 +1012 4 2 0 0 94 353 61 77 +1013 4 2 0 0 110 353 87 107 +1014 4 2 0 0 251 245 322 201 +1015 4 2 0 0 245 179 322 201 +1016 4 2 0 0 11 422 486 14 +1017 4 2 0 0 287 588 464 528 +1018 4 2 0 0 10 467 412 551 +1019 4 2 0 0 13 551 412 467 +1020 4 2 0 0 371 467 551 13 +1021 4 2 0 0 551 10 8 412 +1022 4 2 0 0 113 164 361 136 +1023 4 2 0 0 425 25 15 26 +1024 4 2 0 0 140 348 125 160 +1025 4 2 0 0 451 588 528 286 +1026 4 2 0 0 180 152 145 141 +1027 4 2 0 0 607 16 539 470 +1028 4 2 0 0 374 570 400 373 +1029 4 2 0 0 373 374 556 400 +1030 4 2 0 0 374 373 556 628 +1031 4 2 0 0 441 628 578 483 +1032 4 2 0 0 497 642 418 629 +1033 4 2 0 0 167 89 106 339 +1034 4 2 0 0 346 440 390 521 +1035 4 2 0 0 369 123 342 375 +1036 4 2 0 0 583 382 498 361 +1037 4 2 0 0 564 75 72 61 +1038 4 2 0 0 564 61 64 75 +1039 4 2 0 0 345 517 79 92 +1040 4 2 0 0 533 529 223 222 +1041 4 2 0 0 498 582 576 375 +1042 4 2 0 0 575 376 609 49 +1043 4 2 0 0 412 10 8 447 +1044 4 2 0 0 561 472 549 468 +1045 4 2 0 0 239 322 252 231 +1046 4 2 0 0 397 12 4 14 +1047 4 2 0 0 367 369 434 576 +1048 4 2 0 0 206 313 322 179 +1049 4 2 0 0 322 179 313 354 +1050 4 2 0 0 12 2 4 7 +1051 4 2 0 0 346 638 26 608 +1052 4 2 0 0 66 87 57 58 +1053 4 2 0 0 72 58 564 61 +1054 4 2 0 0 322 207 231 239 +1055 4 2 0 0 201 354 322 207 +1056 4 2 0 0 239 255 322 201 +1057 4 2 0 0 533 402 529 222 +1058 4 2 0 0 60 518 564 65 +1059 4 2 0 0 11 486 12 14 +1060 4 2 0 0 118 168 141 152 +1061 4 2 0 0 60 376 564 518 +1062 4 2 0 0 576 375 582 115 +1063 4 2 0 0 515 34 399 351 +1064 4 2 0 0 334 564 64 363 +1065 4 2 0 0 311 331 150 305 +1066 4 2 0 0 473 538 597 519 +1067 4 2 0 0 564 594 575 475 +1068 4 2 0 0 36 30 432 410 +1069 4 2 0 0 343 396 356 279 +1070 4 2 0 0 281 279 356 396 +1071 4 2 0 0 281 274 301 356 +1072 4 2 0 0 486 7 14 422 +1073 4 2 0 0 642 153 585 629 +1074 4 2 0 0 153 642 628 629 +1075 4 2 0 0 503 447 8 10 +1076 4 2 0 0 461 430 620 416 +1077 4 2 0 0 493 270 275 280 +1078 4 2 0 0 275 493 532 323 +1079 4 2 0 0 532 493 282 323 +1080 4 2 0 0 461 495 430 416 +1081 4 2 0 0 493 532 280 275 +1082 4 2 0 0 389 381 47 413 +1083 4 2 0 0 49 413 626 527 +1084 4 2 0 0 500 189 186 181 +1085 4 2 0 0 498 382 582 375 +1086 4 2 0 0 410 30 24 377 +1087 4 2 0 0 30 410 36 377 +1088 4 2 0 0 366 265 279 272 +1089 4 2 0 0 608 34 32 31 +1090 4 2 0 0 527 40 43 38 +1091 4 2 0 0 46 527 41 38 +1092 4 2 0 0 43 527 38 41 +1093 4 2 0 0 597 639 7 486 +1094 4 2 0 0 306 298 336 331 +1095 4 2 0 0 11 26 15 543 +1096 4 2 0 0 554 11 15 543 +1097 4 2 0 0 416 430 620 649 +1098 4 2 0 0 291 290 364 327 +1099 4 2 0 0 637 498 375 361 +1100 4 2 0 0 39 548 33 461 +1101 4 2 0 0 422 634 25 543 +1102 4 2 0 0 583 582 382 113 +1103 4 2 0 0 367 114 118 141 +1104 4 2 0 0 473 422 11 554 +1105 4 2 0 0 178 197 168 141 +1106 4 2 0 0 375 369 123 115 +1107 4 2 0 0 91 123 115 375 +1108 4 2 0 0 377 350 36 553 +1109 4 2 0 0 173 181 516 186 +1110 4 2 0 0 110 95 107 87 +1111 4 2 0 0 353 107 163 87 +1112 4 2 0 0 46 527 42 610 +1113 4 2 0 0 500 209 348 202 +1114 4 2 0 0 334 61 564 57 +1115 4 2 0 0 510 103 140 161 +1116 4 2 0 0 160 104 140 133 +1117 4 2 0 0 486 11 473 422 +1118 4 2 0 0 336 611 331 514 +1119 4 2 0 0 576 434 637 369 +1120 4 2 0 0 29 466 524 20 +1121 4 2 0 0 366 279 265 258 +1122 4 2 0 0 366 279 258 274 +1123 4 2 0 0 89 484 338 454 +1124 4 2 0 0 462 621 568 534 +1125 4 2 0 0 133 104 140 103 +1126 4 2 0 0 462 534 568 531 +1127 4 2 0 0 521 440 390 563 +1128 4 2 0 0 383 440 563 390 +1129 4 2 0 0 141 154 170 369 +1130 4 2 0 0 141 193 369 170 +1131 4 2 0 0 173 181 510 516 +1132 4 2 0 0 348 510 181 516 +1133 4 2 0 0 324 366 276 272 +1134 4 2 0 0 415 324 366 323 +1135 4 2 0 0 477 527 507 43 +1136 4 2 0 0 26 25 440 346 +1137 4 2 0 0 430 333 42 479 +1138 4 2 0 0 460 452 564 75 +1139 4 2 0 0 31 515 32 592 +1140 4 2 0 0 181 189 187 500 +1141 4 2 0 0 389 527 413 47 +1142 4 2 0 0 413 389 626 527 +1143 4 2 0 0 376 590 49 575 +1144 4 2 0 0 331 611 185 508 +1145 4 2 0 0 223 392 407 219 +1146 4 2 0 0 223 233 392 219 +1147 4 2 0 0 538 648 597 519 +1148 4 2 0 0 597 648 538 486 +1149 4 2 0 0 557 537 568 499 +1150 4 2 0 0 553 39 461 416 +1151 4 2 0 0 290 528 451 287 +1152 4 2 0 0 554 453 332 560 +1153 4 2 0 0 601 467 458 9 +1154 4 2 0 0 623 525 535 566 +1155 4 2 0 0 566 525 535 526 +1156 4 2 0 0 378 106 431 418 +1157 4 2 0 0 53 496 352 347 +1158 4 2 0 0 564 300 419 72 +1159 4 2 0 0 564 452 300 72 +1160 4 2 0 0 2 6 7 486 +1161 4 2 0 0 421 451 528 286 +1162 4 2 0 0 451 528 588 287 +1163 4 2 0 0 409 595 433 491 +1164 4 2 0 0 79 621 78 401 +1165 4 2 0 0 401 621 78 555 +1166 4 2 0 0 78 537 555 621 +1167 4 2 0 0 599 340 282 301 +1168 4 2 0 0 493 599 282 301 +1169 4 2 0 0 430 620 42 333 +1170 4 2 0 0 565 498 112 637 +1171 4 2 0 0 583 498 112 565 +1172 4 2 0 0 599 429 536 282 +1173 4 2 0 0 599 625 459 429 +1174 4 2 0 0 543 554 332 15 +1175 4 2 0 0 474 112 637 565 +1176 4 2 0 0 364 290 528 327 +1177 4 2 0 0 548 461 479 333 +1178 4 2 0 0 461 333 430 479 +1179 4 2 0 0 383 390 346 440 +1180 4 2 0 0 65 60 64 564 +1181 4 2 0 0 65 64 75 564 +1182 4 2 0 0 383 638 346 390 +1183 4 2 0 0 380 468 614 549 +1184 4 2 0 0 532 282 276 323 +1185 4 2 0 0 157 331 504 150 +1186 4 2 0 0 89 454 338 339 +1187 4 2 0 0 167 454 89 339 +1188 4 2 0 0 8 5 10 551 +1189 4 2 0 0 5 520 10 551 +1190 4 2 0 0 492 626 545 389 +1191 4 2 0 0 389 626 545 469 +1192 4 2 0 0 37 33 35 29 +1193 4 2 0 0 615 568 499 557 +1194 4 2 0 0 500 186 480 202 +1195 4 2 0 0 54 56 53 496 +1196 4 2 0 0 294 295 291 385 +1197 4 2 0 0 295 291 385 327 +1198 4 2 0 0 295 294 292 385 +1199 4 2 0 0 474 637 361 565 +1200 4 2 0 0 497 373 426 540 +1201 4 2 0 0 40 29 28 34 +1202 4 2 0 0 535 525 581 526 +1203 4 2 0 0 328 92 79 517 +1204 4 2 0 0 496 56 352 604 +1205 4 2 0 0 459 536 646 493 +1206 4 2 0 0 459 429 624 536 +1207 4 2 0 0 493 536 280 532 +1208 4 2 0 0 25 346 26 608 +1209 4 2 0 0 351 399 41 38 +1210 4 2 0 0 43 41 38 351 +1211 4 2 0 0 527 413 47 606 +1212 4 2 0 0 308 252 322 231 +1213 4 2 0 0 308 255 322 252 +1214 4 2 0 0 256 231 252 308 +1215 4 2 0 0 256 308 259 247 +1216 4 2 0 0 21 30 24 410 +1217 4 2 0 0 21 30 562 24 +1218 4 2 0 0 315 621 555 568 +1219 4 2 0 0 217 219 223 407 +1220 4 2 0 0 225 223 219 233 +1221 4 2 0 0 407 217 529 223 +1222 4 2 0 0 381 452 300 564 +1223 4 2 0 0 595 635 433 491 +1224 4 2 0 0 414 385 291 327 +1225 4 2 0 0 416 39 461 495 +1226 4 2 0 0 461 39 548 495 +1227 4 2 0 0 461 548 479 495 +1228 4 2 0 0 301 282 281 464 +1229 4 2 0 0 301 282 285 340 +1230 4 2 0 0 315 621 568 462 +1231 4 2 0 0 372 289 288 285 +1232 4 2 0 0 289 288 285 414 +1233 4 2 0 0 431 153 106 378 +1234 4 2 0 0 55 641 589 436 +1235 4 2 0 0 651 572 638 608 +1236 4 2 0 0 564 452 72 75 +1237 4 2 0 0 573 534 567 613 +1238 4 2 0 0 567 645 600 534 +1239 4 2 0 0 499 568 577 537 +1240 4 2 0 0 414 327 291 364 +1241 4 2 0 0 561 549 614 468 +1242 4 2 0 0 338 489 566 64 +1243 4 2 0 0 89 484 489 338 +1244 4 2 0 0 385 294 465 344 +1245 4 2 0 0 445 196 444 209 +1246 4 2 0 0 209 550 444 427 +1247 4 2 0 0 490 14 11 12 +1248 4 2 0 0 490 18 14 12 +1249 4 2 0 0 597 648 486 7 +1250 4 2 0 0 486 639 7 422 +1251 4 2 0 0 639 473 597 631 +1252 4 2 0 0 529 491 616 533 +1253 4 2 0 0 435 320 125 373 +1254 4 2 0 0 616 491 529 541 +1255 4 2 0 0 497 628 642 629 +1256 4 2 0 0 46 52 413 602 +1257 4 2 0 0 623 359 566 338 +1258 4 2 0 0 497 506 629 418 +1259 4 2 0 0 99 359 623 338 +1260 4 2 0 0 65 64 454 75 +1261 4 2 0 0 209 617 550 427 +1262 4 2 0 0 86 328 144 128 +1263 4 2 0 0 570 187 374 368 +1264 4 2 0 0 403 86 633 328 +1265 4 2 0 0 601 522 458 523 +1266 4 2 0 0 604 352 472 56 +1267 4 2 0 0 273 312 319 324 +1268 4 2 0 0 380 614 63 549 +1269 4 2 0 0 561 549 63 614 +1270 4 2 0 0 623 525 566 359 +1271 4 2 0 0 359 525 566 526 +1272 4 2 0 0 566 89 526 489 +1273 4 2 0 0 113 382 358 471 +1274 4 2 0 0 582 471 382 113 +1275 4 2 0 0 523 467 458 601 +1276 4 2 0 0 268 308 260 263 +1277 4 2 0 0 374 628 556 578 +1278 4 2 0 0 498 582 382 583 +1279 4 2 0 0 586 645 534 557 +1280 4 2 0 0 361 176 369 136 +1281 4 2 0 0 277 356 274 279 +1282 4 2 0 0 576 637 375 369 +1283 4 2 0 0 637 375 369 361 +1284 4 2 0 0 373 556 569 400 +1285 4 2 0 0 556 373 569 628 +1286 4 2 0 0 447 562 24 21 +1287 4 2 0 0 47 492 527 507 +1288 4 2 0 0 495 39 548 487 +1289 4 2 0 0 572 608 651 650 +1290 4 2 0 0 541 619 542 574 +1291 4 2 0 0 27 562 21 30 +1292 4 2 0 0 21 446 562 27 +1293 4 2 0 0 517 328 614 79 +1294 4 2 0 0 545 530 622 575 +1295 4 2 0 0 522 371 523 558 +1296 4 2 0 0 523 371 520 558 +1297 4 2 0 0 471 91 115 375 +1298 4 2 0 0 578 127 628 556 +1299 4 2 0 0 127 153 628 556 +1300 4 2 0 0 641 413 55 52 +1301 4 2 0 0 55 564 436 58 +1302 4 2 0 0 564 334 57 594 +1303 4 2 0 0 55 641 436 413 +1304 4 2 0 0 575 413 49 594 +1305 4 2 0 0 15 17 596 560 +1306 4 2 0 0 521 440 563 571 +1307 4 2 0 0 632 581 62 526 +1308 4 2 0 0 285 372 301 340 +1309 4 2 0 0 290 451 528 421 +1310 4 2 0 0 326 57 564 58 +1311 4 2 0 0 205 212 241 204 +1312 4 2 0 0 564 452 469 381 +1313 4 2 0 0 239 322 207 201 +1314 4 2 0 0 223 392 529 407 +1315 4 2 0 0 381 564 413 469 +1316 4 2 0 0 395 513 311 186 +1317 4 2 0 0 389 469 413 626 +1318 4 2 0 0 136 361 583 565 +1319 4 2 0 0 586 645 567 534 +1320 4 2 0 0 32 25 608 346 +1321 4 2 0 0 369 367 137 141 +1322 4 2 0 0 469 575 545 622 +1323 4 2 0 0 593 543 634 422 +1324 4 2 0 0 373 569 628 591 +1325 4 2 0 0 556 569 153 628 +1326 4 2 0 0 196 187 373 570 +1327 4 2 0 0 167 454 339 155 +1328 4 2 0 0 590 626 575 530 +1329 4 2 0 0 536 493 282 532 +1330 4 2 0 0 133 140 160 510 +1331 4 2 0 0 376 363 64 564 +1332 4 2 0 0 209 427 444 587 +1333 4 2 0 0 571 440 563 383 +1334 4 2 0 0 498 375 576 637 +1335 4 2 0 0 531 534 568 579 +1336 4 2 0 0 534 568 557 621 +1337 4 2 0 0 218 392 643 238 +1338 4 2 0 0 568 555 577 537 +1339 4 2 0 0 475 609 363 49 +1340 4 2 0 0 363 609 475 564 +1341 4 2 0 0 393 311 150 305 +1342 4 2 0 0 19 425 17 596 +1343 4 2 0 0 596 17 603 560 +1344 4 2 0 0 522 428 371 558 +1345 4 2 0 0 127 628 497 483 +1346 4 2 0 0 492 48 545 626 +1347 4 2 0 0 21 607 24 580 +1348 4 2 0 0 132 117 318 128 +1349 4 2 0 0 633 132 547 142 +1350 4 2 0 0 437 381 419 413 +1351 4 2 0 0 419 381 437 300 +1352 4 2 0 0 173 181 186 171 +1353 4 2 0 0 405 613 600 534 +1354 4 2 0 0 632 526 62 64 +1355 4 2 0 0 489 484 64 338 +1356 4 2 0 0 600 54 53 621 +1357 4 2 0 0 29 20 28 466 +1358 4 2 0 0 20 28 466 443 +1359 4 2 0 0 49 48 626 590 +1360 4 2 0 0 63 345 614 380 +1361 4 2 0 0 584 345 63 380 +1362 4 2 0 0 470 607 559 478 +1363 4 2 0 0 28 23 22 20 +1364 4 2 0 0 478 23 22 28 +1365 4 2 0 0 473 422 554 631 +1366 4 2 0 0 555 537 568 621 +1367 4 2 0 0 18 490 14 439 +1368 4 2 0 0 596 17 19 603 +1369 4 2 0 0 571 440 18 521 +1370 4 2 0 0 542 491 616 541 +1371 4 2 0 0 534 568 615 557 +1372 4 2 0 0 534 568 579 615 +1373 4 2 0 0 392 222 229 238 +1374 4 2 0 0 626 48 530 590 +1375 4 2 0 0 238 406 229 423 +1376 4 2 0 0 629 585 642 418 +1377 4 2 0 0 418 506 629 378 +1378 4 2 0 0 378 431 629 418 +1379 4 2 0 0 153 448 628 591 +1380 4 2 0 0 591 569 628 153 +1381 4 2 0 0 550 209 500 627 +1382 4 2 0 0 515 31 32 34 +1383 4 2 0 0 209 627 550 617 +1384 4 2 0 0 569 556 153 400 +1385 4 2 0 0 645 621 557 54 +1386 4 2 0 0 529 491 533 223 +1387 4 2 0 0 601 1 458 522 +1388 4 2 0 0 522 601 1 3 +1389 4 2 0 0 359 339 99 106 +1390 4 2 0 0 338 99 359 339 +1391 4 2 0 0 49 575 626 413 +1392 4 2 0 0 473 597 631 453 +1393 4 2 0 0 605 564 518 460 +1394 4 2 0 0 222 392 402 529 +1395 4 2 0 0 113 382 583 361 +1396 4 2 0 0 33 335 28 23 +1397 4 2 0 0 370 52 594 46 +1398 4 2 0 0 408 505 580 607 +1399 4 2 0 0 413 640 602 641 +1400 4 2 0 0 630 376 564 609 +1401 4 2 0 0 49 376 609 363 +1402 4 2 0 0 363 376 609 564 +1403 4 2 0 0 393 456 311 305 +1404 4 2 0 0 218 221 386 643 +1405 4 2 0 0 643 386 423 221 +1406 4 2 0 0 141 123 369 367 +1407 4 2 0 0 498 382 375 361 +1408 4 2 0 0 474 637 369 361 +1409 4 2 0 0 558 371 520 551 +1410 4 2 0 0 558 428 371 551 +1411 4 2 0 0 374 441 411 373 +1412 4 2 0 0 422 25 26 543 +1413 4 2 0 0 25 17 15 634 +1414 4 2 0 0 606 44 610 45 +1415 4 2 0 0 367 115 369 576 +1416 4 2 0 0 367 576 546 115 +1417 4 2 0 0 636 573 567 613 +1418 4 2 0 0 615 51 579 573 +1419 4 2 0 0 50 51 615 636 +1420 4 2 0 0 55 413 564 52 +1421 4 2 0 0 594 52 413 46 +1422 4 2 0 0 564 326 52 57 +1423 4 2 0 0 367 434 546 576 +1424 4 2 0 0 208 449 379 445 +1425 4 2 0 0 379 445 544 208 +1426 4 2 0 0 26 439 440 25 +1427 4 2 0 0 622 575 605 469 +1428 4 2 0 0 636 586 567 573 +1429 4 2 0 0 573 586 567 534 +1430 4 2 0 0 599 625 340 283 +1431 4 2 0 0 605 630 518 564 +1432 4 2 0 0 171 510 181 161 +1433 4 2 0 0 32 29 38 34 +1434 4 2 0 0 402 216 392 222 +1435 4 2 0 0 223 222 392 238 +1436 4 2 0 0 389 492 527 47 +1437 4 2 0 0 389 492 626 527 +1438 4 2 0 0 577 555 78 537 +1439 4 2 0 0 315 621 401 555 +1440 4 2 0 0 15 598 634 560 +1441 4 2 0 0 634 17 15 560 +1442 4 2 0 0 481 142 328 633 +1443 4 2 0 0 128 328 144 138 +1444 4 2 0 0 413 610 640 606 +1445 4 2 0 0 640 606 610 45 +1446 4 2 0 0 379 449 444 445 +1447 4 2 0 0 187 449 196 444 +1448 4 2 0 0 445 449 444 196 +1449 4 2 0 0 605 564 460 469 +1450 4 2 0 0 575 564 605 469 +1451 4 2 0 0 541 200 619 574 +1452 4 2 0 0 564 436 419 413 +1453 4 2 0 0 517 482 63 614 +1454 4 2 0 0 154 369 141 123 +1455 4 2 0 0 583 498 565 361 +1456 4 2 0 0 498 361 637 565 +1457 4 2 0 0 622 530 630 575 +1458 4 2 0 0 21 30 432 27 +1459 4 2 0 0 173 510 160 516 +1460 4 2 0 0 311 160 348 516 +1461 4 2 0 0 485 140 540 373 +1462 4 2 0 0 21 505 580 447 +1463 4 2 0 0 490 26 439 571 +1464 4 2 0 0 379 544 220 208 +1465 4 2 0 0 348 516 181 186 +1466 4 2 0 0 186 509 311 516 +1467 4 2 0 0 209 202 627 617 +1468 4 2 0 0 433 635 529 491 +1469 4 2 0 0 430 42 620 44 +1470 4 2 0 0 649 430 620 44 +1471 4 2 0 0 529 635 541 491 +1472 4 2 0 0 404 24 410 21 +1473 4 2 0 0 404 410 24 335 +1474 4 2 0 0 89 338 359 339 +1475 4 2 0 0 450 328 482 517 +1476 4 2 0 0 517 328 482 614 +1477 4 2 0 0 78 59 537 621 +1478 4 2 0 0 588 396 281 356 +1479 4 2 0 0 286 488 588 356 +1480 4 2 0 0 424 543 593 422 +1481 4 2 0 0 463 607 408 16 +1482 4 2 0 0 389 381 413 469 +1483 4 2 0 0 413 469 575 626 +1484 4 2 0 0 626 469 575 545 +1485 4 2 0 0 554 11 543 422 +1486 4 2 0 0 459 624 646 536 +1487 4 2 0 0 332 543 593 424 +1488 4 2 0 0 631 554 424 422 +1489 4 2 0 0 153 431 629 378 +1490 4 2 0 0 545 48 530 626 +1491 4 2 0 0 626 530 545 575 +1492 4 2 0 0 59 621 78 79 +1493 4 2 0 0 160 510 348 516 +1494 4 2 0 0 626 590 575 49 +1495 4 2 0 0 576 434 112 637 +1496 4 2 0 0 498 576 112 637 +1497 4 2 0 0 346 651 638 608 +1498 4 2 0 0 13 442 412 362 +1499 4 2 0 0 13 467 412 442 +1500 4 2 0 0 132 142 633 128 +1501 4 2 0 0 184 180 172 170 +1502 4 2 0 0 631 332 424 554 +1503 4 2 0 0 531 573 579 51 +1504 4 2 0 0 521 571 563 18 +1505 4 2 0 0 599 625 282 340 +1506 4 2 0 0 622 630 605 575 +1507 4 2 0 0 562 442 362 412 +1508 4 2 0 0 193 180 170 141 +1509 4 2 0 0 50 644 636 615 +1510 4 2 0 0 443 466 20 19 +1511 4 2 0 0 616 542 533 491 +1512 4 2 0 0 413 594 564 52 +1513 4 2 0 0 621 53 600 405 +1514 4 2 0 0 362 562 446 27 +1515 4 2 0 0 403 547 321 481 +1516 4 2 0 0 403 481 321 329 +1517 4 2 0 0 562 442 412 10 +1518 4 2 0 0 493 459 536 599 +1519 4 2 0 0 493 599 536 282 +1520 4 2 0 0 450 86 328 517 +1521 4 2 0 0 413 602 610 46 +1522 4 2 0 0 29 23 28 20 +1523 4 2 0 0 223 409 433 491 +1524 4 2 0 0 621 59 537 54 +1525 4 2 0 0 13 362 412 446 +1526 4 2 0 0 439 422 11 14 +1527 4 2 0 0 639 473 631 422 +1528 4 2 0 0 450 612 584 517 +1529 4 2 0 0 450 482 612 517 +1530 4 2 0 0 413 641 602 52 +1531 4 2 0 0 447 10 24 562 +1532 4 2 0 0 531 573 534 579 +1533 4 2 0 0 380 345 468 604 +1534 4 2 0 0 587 427 444 618 +1535 4 2 0 0 613 567 600 534 +1536 4 2 0 0 218 386 238 643 +1537 4 2 0 0 643 238 423 386 +1538 4 2 0 0 347 496 352 604 +1539 4 2 0 0 63 345 517 614 +1540 4 2 0 0 584 612 63 517 +1541 4 2 0 0 629 431 585 418 +1542 4 2 0 0 153 431 585 629 +1543 4 2 0 0 463 539 478 607 +1544 4 2 0 0 463 539 607 16 +1545 4 2 0 0 564 609 475 575 +1546 4 2 0 0 533 529 402 616 +1547 4 2 0 0 376 630 564 518 +1548 4 2 0 0 645 54 600 621 +1549 4 2 0 0 380 468 472 604 +1550 4 2 0 0 604 468 472 352 +1551 4 2 0 0 380 468 549 472 +1552 4 2 0 0 570 187 373 374 +1553 4 2 0 0 606 413 641 640 +1554 4 2 0 0 413 610 602 640 +1555 4 2 0 0 458 467 13 9 +1556 4 2 0 0 467 458 13 371 +1557 4 2 0 0 11 422 26 543 +1558 4 2 0 0 25 17 425 15 +1559 4 2 0 0 646 536 280 493 +1560 4 2 0 0 646 624 280 536 +1561 4 2 0 0 647 430 44 42 +1562 4 2 0 0 618 544 220 379 +1563 4 2 0 0 648 6 486 7 +1564 4 2 0 0 648 6 538 486 +1565 4 2 0 0 403 633 547 481 +1566 4 2 0 0 403 328 633 481 +1567 4 2 0 0 483 127 628 578 +1568 4 2 0 0 486 7 12 14 +1569 4 2 0 0 53 56 352 496 +1570 4 2 0 0 340 288 284 625 +1571 4 2 0 0 283 340 284 625 +1572 4 2 0 0 561 352 472 468 +1573 4 2 0 0 86 450 328 403 +1574 4 2 0 0 329 403 481 328 +1575 4 2 0 0 455 288 284 372 +1576 4 2 0 0 501 288 284 455 +1577 4 2 0 0 376 530 575 630 +1578 4 2 0 0 630 376 609 575 +1579 4 2 0 0 430 479 42 647 +1580 4 2 0 0 621 405 600 534 +1581 4 2 0 0 22 28 20 443 +1582 4 2 0 0 643 238 229 423 +1583 4 2 0 0 481 633 547 142 +1584 4 2 0 0 558 428 551 652 +1585 4 2 0 0 509 611 331 508 +1586 4 2 0 0 513 514 331 611 +1587 4 2 0 0 509 513 331 611 +1588 4 2 0 0 601 9 1 3 +1589 4 2 0 0 289 288 344 501 +1590 4 2 0 0 515 32 399 34 +1591 4 2 0 0 403 321 349 329 +1592 4 2 0 0 392 229 643 238 +1593 4 2 0 0 618 445 544 379 +1594 4 2 0 0 618 587 544 445 +1595 4 2 0 0 531 613 534 573 +1596 4 2 0 0 629 153 448 628 +1597 4 2 0 0 538 473 597 486 +1598 4 2 0 0 597 473 639 486 +1599 4 2 0 0 650 31 608 346 +1600 4 2 0 0 607 505 580 21 +1601 4 2 0 0 288 455 289 372 +1602 4 2 0 0 289 455 288 501 +1603 4 2 0 0 376 530 590 575 +1604 4 2 0 0 49 594 475 575 +1605 4 2 0 0 356 279 281 274 +1606 4 2 0 0 550 209 444 500 +1607 4 2 0 0 362 412 446 562 +1608 4 2 0 0 529 433 491 223 +1609 4 2 0 0 455 372 284 283 +1610 4 2 0 0 465 501 455 289 +1611 4 2 0 0 465 289 344 501 +1612 4 2 0 0 445 209 444 587 +1613 4 2 0 0 153 642 127 628 +1614 4 2 0 0 294 385 291 414 +1615 4 2 0 0 283 625 459 599 +1616 4 2 0 0 613 531 51 573 +1617 4 2 0 0 636 573 613 51 +1618 4 2 0 0 557 621 568 537 +1619 4 2 0 0 558 551 520 5 +1620 4 2 0 0 500 209 202 627 +1621 4 2 0 0 635 200 541 574 +1622 4 2 0 0 595 200 635 574 +1623 4 2 0 0 558 652 551 5 +1624 4 2 0 0 534 579 573 615 +1625 4 2 0 0 605 575 630 564 +1626 4 2 0 0 31 346 32 608 +1627 4 2 0 0 631 424 639 422 +1628 4 2 0 0 383 346 638 26 +1629 4 2 0 0 469 575 564 413 +1630 4 2 0 0 15 560 332 598 +1631 4 2 0 0 15 554 332 560 +1632 4 2 0 0 586 557 534 615 +1633 4 2 0 0 573 586 534 615 +1634 4 2 0 0 332 543 598 593 +1635 4 2 0 0 543 332 598 15 +1636 4 2 0 0 609 575 564 630 +1637 4 2 0 0 554 631 332 453 +1638 4 2 0 0 424 554 543 422 +1639 4 2 0 0 608 346 651 650 +1640 4 2 0 0 487 495 430 479 +1641 4 2 0 0 645 621 534 557 +1642 4 2 0 0 645 621 600 534 +1643 4 2 0 0 542 491 541 574 +1644 4 2 0 0 541 635 574 491 +1645 4 2 0 0 636 644 586 573 +1646 4 2 0 0 573 586 615 644 +1647 4 2 0 0 543 634 598 593 +1648 4 2 0 0 497 127 642 628 +1649 4 2 0 0 598 543 15 634 +1650 4 2 0 0 25 15 543 634 +1651 4 2 0 0 473 519 597 453 +1652 4 2 0 0 595 574 635 491 +1653 4 2 0 0 636 51 615 573 +1654 4 2 0 0 644 573 636 615 +$EndElements diff --git a/test/user/testdata/shark_22_ascii_gmshApp.xml b/test/user/testdata/shark_22_ascii_gmshApp.xml new file mode 100644 index 00000000..a7946939 --- /dev/null +++ b/test/user/testdata/shark_22_ascii_gmshApp.xml @@ -0,0 +1,25 @@ + + diff --git a/test/user/testdata/shark_22_ascii_missing_element.msh b/test/user/testdata/shark_22_ascii_missing_element.msh new file mode 100644 index 00000000..d768cd12 --- /dev/null +++ b/test/user/testdata/shark_22_ascii_missing_element.msh @@ -0,0 +1,3978 @@ +$MeshFormat +2.2 0 8 +$EndMeshFormat +$Nodes +652 +1 -0.0733436 0.0816748 0.056402 +2 -0.0729126 0.0537921 0.00170478 +3 -0.072634 0.0799069 0.0578949 +4 -0.0715817 0.0520377 0.00292576 +5 -0.0701949 0.0802569 0.0450431 +6 -0.0687698 0.060971 0.00326551 +7 -0.06778 0.060358 0.00473741 +8 -0.0672796 0.0809249 0.0425553 +9 -0.0658074 0.0806443 0.0552302 +10 -0.064933 0.0788176 0.0453762 +11 -0.0636555 0.0610198 0.00141989 +12 -0.0636111 0.0566004 -0.000556663 +13 -0.0636791 0.0819076 0.0524468 +14 -0.0623445 0.0580268 0.00335683 +15 -0.0624856 0.0671058 0.00581638 +16 -0.0601398 0.0781111 0.0317589 +17 -0.0599443 0.0685632 0.00992449 +18 -0.0592787 0.0571239 0.00105116 +19 -0.0587906 0.0719999 0.0117948 +20 -0.0575605 0.0730663 0.016213 +21 -0.057624 0.0811803 0.0403639 +22 -0.0572339 0.0769387 0.0223219 +23 -0.0559974 0.0749629 0.0235691 +24 -0.0542321 0.0763209 0.0344665 +25 -0.0540672 0.0649483 0.00821813 +26 -0.0541685 0.0661135 0.00437935 +27 -0.0532966 0.0805356 0.0466758 +28 -0.0517252 0.0761185 0.0183218 +29 -0.0505257 0.068877 0.0152572 +30 -0.0503803 0.0772638 0.0406423 +31 -0.0472855 0.0641041 0.00381053 +32 -0.0469016 0.0648796 0.00821733 +33 -0.0474599 0.0727268 0.0265623 +34 -0.0464733 0.070912 0.0103373 +35 -0.0444756 0.0755674 0.0221683 +36 -0.0440208 0.0774313 0.0371107 +37 -0.0434135 0.0685101 0.0213943 +38 -0.0425401 0.0668787 0.0159114 +39 -0.0405353 0.0730163 0.0309862 +40 -0.0386417 0.073548 0.0160682 +41 -0.037401 0.0664899 0.0122191 +42 -0.0358693 0.0689445 0.0243885 +43 -0.0351058 0.0687771 0.0124837 +44 -0.0333614 0.071165 0.0238503 +45 -0.0325564 0.0696271 0.024504 +46 -0.032455 0.0625178 0.0200737 +47 -0.0305469 0.0729973 0.0173921 +48 -0.0276941 0.0652386 0.0128238 +49 -0.0272717 0.0628782 0.0141328 +50 -0.0263428 0.00735496 0.00505748 +51 -0.0256055 0.00658056 0.00327552 +52 -0.0252856 0.0610141 0.0227762 +53 -0.0250237 -0.00678856 0.00359213 +54 -0.0242889 -0.00589458 0.00589675 +55 -0.0216872 0.0639735 0.0255561 +56 -0.0215721 -0.0119744 0.00619585 +57 -0.0195136 0.0542304 0.0216195 +58 -0.0168343 0.0649534 0.0236547 +59 -0.0161373 -0.00420129 0.00881529 +60 -0.0148726 0.0585475 0.0106707 +61 -0.0140647 0.0517836 0.0159197 +62 -0.0142986 0.0543801 0.0051496 +63 -0.0139611 -0.0178642 0.00651265 +64 -0.0139803 0.0554055 0.0115694 +65 -0.0124373 0.0606817 0.0122622 +66 -0.0127423 0.0580719 0.0285553 +67 -0.0127412 -0.0704232 0.0234664 +68 -0.0126173 -0.0801905 0.022154 +69 -0.0125269 0.0592002 0.0346418 +70 -0.0122498 -0.080596 0.0191154 +71 -0.0121442 -0.0691943 0.0191352 +72 -0.0123618 0.0658492 0.0197519 +73 -0.0121018 -0.063334 0.0245151 +74 -0.0118539 0.0462485 0.0243954 +75 -0.0111067 0.0637388 0.0161162 +76 -0.0110042 -0.0624802 0.0276395 +77 -0.0109072 0.046219 0.0183571 +78 -0.0107037 -0.000325242 0.00950432 +79 -0.010183 -0.0121386 0.00674337 +80 -0.00977442 -0.0638147 0.0162637 +81 -0.0097669 -0.0699334 0.0156591 +82 -0.00942656 -0.0836042 0.0182705 +83 -0.009321 -0.0852334 0.0216727 +84 -0.00803502 0.0401179 0.0263407 +85 -0.00857808 -0.0579335 0.0163943 +86 -0.00793158 -0.0190616 0.0121625 +87 -0.00782675 0.0573514 0.028038 +88 -0.00773028 -0.0620746 0.0302044 +89 -0.00764665 0.0537773 0.00961295 +90 -0.00721562 -0.0507362 0.0224357 +91 -0.00717408 -0.0528249 0.0179333 +92 -0.00651588 -0.00739691 0.013024 +93 -0.00691116 -0.00014073 0.00823716 +94 -0.00661131 0.044183 0.0123 +95 -0.00658663 0.0535365 0.0326225 +96 -0.00630954 -0.0850657 0.0194796 +97 -0.00616497 -0.0797841 0.0261073 +98 -0.00582999 -0.0494502 0.0287705 +99 -0.00563359 0.0476479 0.00934546 +100 -0.00506609 -0.0425596 0.0250833 +101 -0.00453974 -0.0405694 0.0173853 +102 -0.00447266 0.0319291 0.0205877 +103 -0.00434886 0.0267225 0.00648417 +104 -0.00418386 0.0253438 0.00842196 +105 -0.0041733 -0.0606038 0.0122716 +106 -0.00385183 0.0479538 0.00869149 +107 -0.00333705 0.051389 0.031593 +108 -0.00333565 -0.0693881 0.0119551 +109 -0.00333748 -0.0650683 0.0110291 +110 -0.00292457 0.0475597 0.0319288 +111 -0.00280471 -0.0353375 0.0238411 +112 -0.00273019 -0.0493159 0.0135756 +113 -0.00255346 -0.0452657 0.0126112 +114 -0.00249178 -0.0598565 0.010934 +115 -0.00247351 -0.0533955 0.0149632 +116 -0.00280465 0.0288144 0.0300227 +117 -0.00225175 -0.030519 0.0236922 +118 -0.00205777 -0.0595101 0.00715068 +119 -0.0018581 -0.0627033 0.0116048 +120 -0.00150112 -0.0384203 0.0313885 +121 -0.00143547 -0.0337232 0.0176227 +122 -0.00136747 -0.062725 0.0150152 +123 -0.000884775 -0.0587825 0.0143119 +124 -0.000624659 -0.0247814 0.0257906 +125 -0.000489974 0.0225414 0.0188523 +126 -6.05566e-05 0.0171338 0.0234086 +127 0.00150381 0.0360475 0.00675461 +128 0.000282178 -0.0241462 0.0174969 +129 0.000347869 -0.0675237 0.0324883 +130 0.000429839 -0.0422219 0.0349169 +131 0.00028168 -0.0273698 0.0312235 +132 0.000952705 -0.0267391 0.0143612 +133 0.00105244 0.0186951 0.00689988 +134 0.0011109 -0.0779453 0.014663 +135 0.00137887 0.00842564 0.0258445 +136 0.00107238 -0.0462225 0.00980545 +137 0.00158113 -0.0561697 0.005809 +138 0.00165921 -0.0142314 0.0114909 +139 0.00169065 -0.00330978 0.027848 +140 0.0017282 0.0264299 0.00972258 +141 0.00196109 -0.062067 0.0125082 +142 0.00198494 -0.0249792 0.0122768 +143 0.00206797 -0.0322322 0.0125632 +144 0.00219287 -0.00991015 0.0199027 +145 0.00223228 -0.065619 0.00972103 +146 0.00226787 -0.06664 0.0139131 +147 0.00233081 0.00970751 0.0349608 +148 0.0023033 -0.0550711 0.0357611 +149 0.00284591 -0.0695874 0.0109337 +150 0.00313658 0.0123831 0.0152878 +151 0.00325266 -0.000639164 0.0164744 +152 0.00354678 -0.0651674 0.00553443 +153 0.00434877 0.0392681 0.00656793 +154 0.0034004 -0.0624097 0.0143354 +155 0.00410027 0.052311 0.0146156 +156 0.00425687 -0.0110681 0.0377954 +157 0.0043501 -0.0020508 0.015115 +158 0.00444422 -0.0785667 0.0168482 +159 0.00471578 -0.00872746 0.0133588 +160 0.00486541 0.0192794 0.0102326 +161 0.00475235 0.0259901 0.00777948 +162 0.00497525 -0.0797755 0.0244877 +163 0.0052286 0.0545416 0.0234287 +164 0.00513856 -0.0361953 0.00904286 +165 0.00543656 -0.016404 0.0117933 +166 0.00521097 0.0361763 0.0357574 +167 0.00563068 0.0458779 0.0101474 +168 0.00602624 -0.0598053 0.00448538 +169 0.00669265 -0.0730234 0.0300997 +170 0.00671975 -0.0647944 0.0149968 +171 0.00743572 0.0219428 0.00498754 +172 0.00806977 -0.0676622 0.0106835 +173 0.00858002 0.0185363 0.00804532 +174 0.00900922 -0.0527441 0.0382868 +175 0.00967438 -0.0310472 0.0412759 +176 0.00969027 -0.0470756 0.00574739 +177 0.00982547 -0.0777201 0.0238208 +178 0.010337 -0.0646559 0.00738197 +179 0.0103691 -0.0715108 0.0301524 +180 0.0108524 -0.0651923 0.0107074 +181 0.0112352 0.0223598 0.00496048 +182 0.0115762 0.0360388 0.034027 +183 0.011811 0.0150563 0.0411225 +184 0.0119389 -0.0710873 0.0142927 +185 0.011481 0.000850754 0.00890493 +186 0.0122581 0.0177891 0.00726338 +187 0.0126044 0.0285097 0.0071727 +188 0.0126077 -0.0410848 0.00487059 +189 0.01325 0.0245576 0.00385279 +190 0.0133342 -0.0301914 0.00695184 +191 0.0134526 -0.00467313 0.044297 +192 0.0140263 0.0415073 0.0128325 +193 0.0139319 -0.0627506 0.0126489 +194 0.0144402 0.0213321 0.0408733 +195 0.0145153 -0.0120242 0.00709154 +196 0.0145254 0.0314471 0.00762861 +197 0.0143606 -0.0539791 0.00638859 +198 0.0153705 -0.0588177 0.00913193 +199 0.0158483 0.0424843 0.0267153 +200 0.0161677 0.0082135 0.0752128 +201 0.0160709 -0.0693691 0.0267104 +202 0.0163112 0.021127 0.00658374 +203 0.0163956 0.0418119 0.0180916 +204 0.0166653 0.00513625 0.0449469 +205 0.0171438 -0.00939438 0.0462661 +206 0.0174416 -0.0497054 0.0373642 +207 0.0174198 -0.0656937 0.0159871 +208 0.0177387 0.0346114 0.0053358 +209 0.0178439 0.0247259 0.00729322 +210 0.018247 0.0346901 0.00258831 +211 0.0182074 -0.0318958 0.0424624 +212 0.0183988 -0.00142899 0.0496692 +213 0.0188182 -0.018825 0.0447569 +214 0.0188285 0.0147456 0.0461032 +215 0.0188626 0.015416 0.041072 +216 0.0190811 -0.00419709 0.0686858 +217 0.0195945 0.0084326 0.064095 +218 0.0197498 -0.00217441 0.0583864 +219 0.0198208 0.00539755 0.0587622 +220 0.0200137 0.0324539 0.00354185 +221 0.020151 -0.0145671 0.0500049 +222 0.0203386 -0.00326709 0.0702447 +223 0.0209148 0.00523036 0.0681576 +224 0.0208447 0.0121045 0.0546374 +225 0.0209724 0.00970633 0.0633876 +226 0.020604 -0.0121123 0.00591309 +227 0.0212498 -0.0289526 0.00565549 +228 0.0216078 -0.0380775 0.00479088 +229 0.0216875 -0.00997672 0.0619769 +230 0.0220658 0.00705093 0.0456869 +231 0.0223002 -0.0558455 0.0110476 +232 0.0223137 -0.0154618 0.0494217 +233 0.0229336 0.00417573 0.0589573 +234 0.0231427 0.0278288 0.0125965 +235 0.0231751 0.027241 0.0309726 +236 0.0233259 0.0160686 0.00756079 +237 0.0234095 0.0318943 0.0199392 +238 0.0234462 -0.00393483 0.0583985 +239 0.0235915 -0.0597066 0.0170609 +240 0.0240196 -0.0108777 0.0466362 +241 0.024123 -0.00330273 0.0464733 +242 0.0242099 -0.0321428 0.0398591 +243 0.0244244 0.00347947 0.0416421 +244 0.024564 -0.0175604 0.0433407 +245 0.0253979 -0.0453083 0.0344803 +246 0.0256103 0.0267734 0.0284514 +247 0.0259312 -0.0445208 0.00878379 +248 0.025959 -0.0133125 0.00624018 +249 0.0265967 -0.0369666 0.00635268 +250 0.0273245 -0.0066598 0.0412078 +251 0.0277597 -0.0467651 0.0304517 +252 0.0275944 -0.0515878 0.0207552 +253 0.0282687 0.0208205 0.0174814 +254 0.0290859 0.0112094 0.012597 +255 0.0293048 -0.0474855 0.0256026 +256 0.0296506 -0.0466043 0.0156453 +257 0.0304236 0.0134394 0.031696 +258 0.0304518 -0.0291908 0.00746031 +259 0.03126 -0.044124 0.016095 +260 0.0321715 -0.043346 0.0242104 +261 0.0322352 -0.0402733 0.0141242 +262 0.0323149 0.01052 0.0200521 +263 0.0324768 -0.0397188 0.0271188 +264 0.0325431 -0.0291932 0.0340382 +265 0.0332479 -0.0329826 0.0117351 +266 0.0338676 -0.0346121 0.0252676 +267 0.0341522 -0.00293196 0.033596 +268 0.0341882 -0.0361716 0.0179088 +269 0.0344969 -0.0256263 0.0309923 +270 0.0345138 -0.00958586 0.0123416 +271 0.0348872 -0.0128566 0.0339912 +272 0.0349524 -0.0273994 0.0177976 +273 0.0349556 -0.000677158 0.0209767 +274 0.0350004 -0.028049 0.00876142 +275 0.0353194 -0.0100316 0.0154749 +276 0.0354214 -0.0195455 0.0173172 +277 0.0355775 -0.0309821 0.0107592 +278 0.0360305 -0.0150581 0.0232372 +279 0.0363938 -0.0285041 0.0132933 +280 0.0374738 -0.00607371 0.0123945 +281 0.041317 -0.0210454 0.0131228 +282 0.0425886 -0.0120136 0.0129537 +283 0.0475164 -0.00753527 0.00853843 +284 0.0492593 -0.00704914 0.00938067 +285 0.0496752 -0.0170405 0.0106038 +286 0.0498676 -0.0259318 0.00619626 +287 0.052402 -0.022331 0.00866719 +288 0.0516897 -0.011391 0.0103437 +289 0.0559595 -0.0106346 0.00698866 +290 0.0596531 -0.0214295 0.0059579 +291 0.066312 -0.0158462 0.00759335 +292 0.0672852 -0.00331292 0.00667068 +293 0.0687074 -0.0027598 0.00829441 +294 0.0687083 -0.0084515 0.00881385 +295 0.0702857 -0.00694567 0.00665748 +296 0.02471 0.00101921 0.00688758 +297 0.00641783 -0.0341512 0.0233596 +298 0.024018 0.00854392 0.00722419 +299 0.0251696 0.00942127 0.00784613 +300 -0.019815 0.0686939 0.0189821 +301 0.0416697 -0.017118 0.00864259 +302 -0.00440288 -0.0698432 0.0205811 +303 -0.0033606 0.0600219 0.0217676 +304 0.0268544 0.00322876 0.0080825 +305 0.00855449 0.0107052 0.00928038 +306 0.0219179 0.00585482 0.0121236 +307 0.0199208 0.0175811 0.0336776 +308 0.0210521 -0.0362113 0.0256186 +309 0.0339797 -0.00194129 0.0163861 +310 0.03202 0.000337126 0.0126992 +311 0.0119633 0.0163586 0.0147908 +312 0.0248778 0.0056119 0.0321775 +313 0.00892971 -0.0563678 0.0287948 +314 0.0174837 0.027107 0.0210333 +315 -0.0170518 0.00346089 0.00554363 +316 0.0144974 -0.0120686 0.0314959 +317 0.00336155 -0.00103205 0.0364574 +318 0.00707711 -0.0204903 0.0185209 +319 0.010517 -0.00309481 0.0232445 +320 -0.00559352 0.0373259 0.0172753 +321 -0.00523735 -0.0230725 0.0111224 +322 0.0151072 -0.0538804 0.0213778 +323 0.0347571 -0.0188174 0.0105515 +324 0.0278657 -0.0183642 0.0156758 +325 -0.00338013 -0.0543805 0.0329679 +326 -0.0196332 0.0593213 0.0251138 +327 0.0648163 -0.0143432 0.00627944 +328 -0.00336175 -0.0187472 0.00979996 +329 -0.0059938 -0.0214388 0.00941436 +330 0.0204933 0.0262773 0.00994486 +331 0.0153554 0.00838654 0.0105168 +332 -0.064082 0.064994 0.00682263 +333 -0.0406296 0.0703091 0.0249838 +334 -0.0197677 0.0563929 0.0156108 +335 -0.0506931 0.0781816 0.0304629 +336 0.0171972 -0.00100568 0.011485 +337 0.0314619 -0.0225976 0.00774901 +338 -0.00980694 0.0515267 0.0104574 +339 -0.00435185 0.0493969 0.0137744 +340 0.0449063 -0.0117353 0.00859937 +341 0.00159087 -0.0450385 0.027858 +342 -0.00469537 -0.0637251 0.0233918 +343 0.0424219 -0.0285632 0.00857374 +344 0.0603894 -0.00835109 0.00935053 +345 -0.0147113 -0.0156046 0.00918376 +346 -0.0528157 0.0611754 0.00480955 +347 -0.0173765 -0.00887149 0.00520522 +348 0.0108104 0.02268 0.0130558 +349 -0.00899905 -0.0208443 0.00915416 +350 -0.0449914 0.0768094 0.0302276 +351 -0.0408502 0.06658 0.00836849 +352 -0.0199988 -0.0118916 0.004906 +353 0.00337131 0.0455887 0.0238561 +354 0.00477413 -0.0721541 0.0211645 +355 -0.00344193 -0.049333 0.032475 +356 0.0427245 -0.0268877 0.00738607 +357 0.0272704 -0.0238375 0.00669928 +358 -0.00610544 -0.0476638 0.0181008 +359 -0.00760153 0.0503529 0.00747858 +360 0.0131109 -0.0422224 0.0405109 +361 0.00214561 -0.0490294 0.0151357 +362 -0.0598224 0.0805424 0.0511855 +363 -0.0204542 0.0588165 0.013102 +364 0.059357 -0.0190886 0.00813027 +365 -0.00100716 0.0422264 0.0325724 +366 0.0325535 -0.0244764 0.012522 +367 -0.000431427 -0.0574818 0.0137747 +368 0.0114251 0.0275734 0.00440942 +369 0.00337666 -0.0559724 0.0148659 +370 -0.0262911 0.0586227 0.0207785 +371 -0.0699467 0.0813567 0.0499003 +372 0.0494602 -0.0133111 0.00757754 +373 0.00758285 0.0333008 0.0104911 +374 0.00657287 0.032122 0.00603963 +375 0.000332803 -0.0511328 0.0180756 +376 -0.021764 0.0620607 0.0118108 +377 -0.0454672 0.075167 0.035911 +378 0.00139884 0.045926 0.0128133 +379 0.0176314 0.0311493 0.00370344 +380 -0.0159418 -0.0158578 0.00793814 +381 -0.0229387 0.0691641 0.0166572 +382 -0.00133409 -0.0449329 0.0187829 +383 -0.0538019 0.0611146 0.00198764 +384 0.0305208 -0.00256491 0.0101919 +385 0.0623596 -0.00697151 0.00683979 +386 0.0236819 -0.00777996 0.0526871 +387 0.0118138 -0.0144241 0.0430193 +388 0.0137156 -0.00365078 0.00732253 +389 -0.0257884 0.0686739 0.0150694 +390 -0.0530331 0.060812 0.00248197 +391 -0.000421194 -0.0523335 0.00879177 +392 0.0193846 -0.00072024 0.0649221 +393 0.00485856 0.0133946 0.0114741 +394 -0.0053823 -0.0743714 0.0141262 +395 0.016958 0.0166471 0.00740593 +396 0.0429338 -0.0266961 0.0110582 +397 -0.0650475 0.05473 0.00191127 +398 0.00924818 0.0356698 0.00715588 +399 -0.042468 0.0652669 0.00790867 +400 0.00699205 0.0348997 0.00576165 +401 -0.012123 0.00171435 0.00688121 +402 0.017741 0.00126373 0.0717161 +403 -0.00477874 -0.0228765 0.0123522 +404 -0.05496 0.0793832 0.0329037 +405 -0.0253736 -0.000654191 0.00342534 +406 0.0220159 -0.0128389 0.0555838 +407 0.0187915 0.00366305 0.0653901 +408 -0.0635923 0.0794618 0.0351284 +409 0.0187293 0.00901455 0.0689246 +410 -0.0507436 0.0790633 0.0364811 +411 0.00440962 0.0291856 0.00589534 +412 -0.0610541 0.0815764 0.0467801 +413 -0.0264169 0.0641898 0.0180225 +414 0.0590681 -0.0129818 0.00969293 +415 0.0316732 -0.013669 0.00892731 +416 -0.0368828 0.0732351 0.028231 +417 0.0147007 -0.0293577 0.0425282 +418 -0.00226105 0.042112 0.00818422 +419 -0.022404 0.068624 0.0211714 +420 0.018834 0.0296379 0.0101126 +421 0.0545664 -0.023882 0.00596013 +422 -0.0610274 0.0626039 0.00623226 +423 0.0209345 -0.0123916 0.0558755 +424 -0.064258 0.0639612 0.00701622 +425 -0.0530259 0.0709966 0.0104874 +426 -0.000350232 0.0328643 0.00950357 +427 0.0179821 0.0260225 0.00525665 +428 -0.071629 0.0809096 0.0500374 +429 0.0431333 -0.00662611 0.0109755 +430 -0.0367738 0.072104 0.0272887 +431 -0.00147996 0.0424733 0.00778004 +432 -0.0489442 0.0792518 0.0424775 +433 0.0178184 0.00830923 0.0698262 +434 -0.00256208 -0.0518644 0.0119693 +435 -0.0024457 0.0347988 0.0115191 +436 -0.0226391 0.067054 0.0236986 +437 -0.0250562 0.070839 0.0181046 +438 0.0157661 -0.010775 0.0444953 +439 -0.0587069 0.0610686 0.00549325 +440 -0.0561989 0.0607157 0.00436391 +441 0.0028322 0.0311045 0.0076099 +442 -0.061857 0.079748 0.0514834 +443 -0.0580072 0.0744854 0.0170926 +444 0.017366 0.0281829 0.00449304 +445 0.0175246 0.0303053 0.00632184 +446 -0.0583716 0.0812348 0.0494755 +447 -0.0627638 0.0811059 0.0418948 +448 0.00958337 0.0391723 0.00889538 +449 0.0164997 0.0327763 0.00400793 +450 -0.0100537 -0.019407 0.0104569 +451 0.0535082 -0.023589 0.00757618 +452 -0.0184567 0.0672393 0.0165986 +453 -0.0660887 0.0639515 0.00557639 +454 -0.0085005 0.0591911 0.0132991 +455 0.0527123 -0.00658592 0.00801901 +456 0.00664445 0.0147496 0.00979726 +457 -0.0323364 0.0646841 0.013176 +458 -0.0684981 0.0817682 0.0541475 +459 0.0424951 -0.00680449 0.0104665 +460 -0.01583 0.0638299 0.0140017 +461 -0.0408586 0.0747808 0.0276312 +462 -0.0213675 0.00505684 0.00440033 +463 -0.0609542 0.0784149 0.029815 +464 0.0458286 -0.0196104 0.0115924 +465 0.0619857 -0.0044448 0.00717137 +466 -0.0549453 0.0736446 0.0144159 +467 -0.0660739 0.0797747 0.0511232 +468 -0.0150243 -0.0138696 0.00597473 +469 -0.0208919 0.0664273 0.014553 +470 -0.0583912 0.0766731 0.0277458 +471 -0.00499489 -0.0492059 0.0154875 +472 -0.0177596 -0.0149926 0.00640227 +473 -0.0656257 0.0638276 0.00437301 +474 -0.00111824 -0.0505712 0.010634 +475 -0.0234714 0.0595273 0.0150887 +476 -0.0117477 -0.00786715 0.0107629 +477 -0.0329423 0.0662408 0.012525 +478 -0.0588644 0.0778049 0.0265316 +479 -0.038272 0.0710121 0.0277124 +480 0.0147178 0.0228905 0.00513556 +481 -0.00242697 -0.0228032 0.0106496 +482 -0.00998317 -0.0196685 0.00798312 +483 0.00194711 0.0338412 0.00734265 +484 -0.0101071 0.0571173 0.0108272 +485 -0.000192036 0.0305177 0.010316 +486 -0.0662236 0.0609953 0.00234663 +487 -0.0383437 0.071981 0.0290737 +488 0.0464353 -0.0271448 0.00729223 +489 -0.0113654 0.0558876 0.00985606 +490 -0.0600686 0.0581853 0.00037707 +491 0.0184892 0.00651809 0.072001 +492 -0.0272353 0.0661385 0.0125002 +493 0.0386787 -0.00939756 0.0110365 +494 -0.00702298 -0.0554164 0.0301677 +495 -0.0387296 0.0725599 0.0291973 +496 -0.0195884 -0.00971304 0.00731553 +497 0.000980398 0.0340005 0.00831153 +498 -0.00251349 -0.0493306 0.0137872 +499 -0.0208118 0.00468072 0.00662791 +500 0.0145465 0.0247675 0.00685396 +501 0.0539643 -0.00601143 0.00911787 +502 0.0615879 -0.00432066 0.00875869 +503 -0.0649217 0.0800024 0.0383643 +504 0.00460493 0.00849738 0.0127005 +505 -0.0606311 0.0803611 0.0379233 +506 -0.00316884 0.0400824 0.00969248 +507 -0.0308482 0.067467 0.0126012 +508 0.0120049 0.00511369 0.00824306 +509 0.0117314 0.0134932 0.00784586 +510 0.0067401 0.0222359 0.00786688 +511 0.000365941 0.0444987 0.0334101 +512 0.00589042 0.0427357 0.0325284 +513 0.0134556 0.013691 0.0071386 +514 0.0155774 0.00572549 0.00675779 +515 -0.0442054 0.0654197 0.00607699 +516 0.00863004 0.0184766 0.00878081 +517 -0.0111016 -0.0170398 0.0107756 +518 -0.0162643 0.06208 0.0123266 +519 -0.0670643 0.0628756 0.0047451 +520 -0.0673064 0.0791769 0.0489333 +521 -0.0566743 0.0588231 0.00264455 +522 -0.0713841 0.080001 0.0523997 +523 -0.0690781 0.0794039 0.0521145 +524 -0.0589744 0.0702988 0.0123753 +525 -0.0108026 0.05228 0.00636676 +526 -0.0113486 0.0541547 0.00728553 +527 -0.0299136 0.0686241 0.0165753 +528 0.0505332 -0.0225927 0.00635398 +529 0.0180077 0.0031318 0.0704387 +530 -0.0235313 0.0640143 0.012641 +531 -0.0235569 0.00584404 0.00381922 +532 0.0384718 -0.0113423 0.0144484 +533 0.0182407 0.00232532 0.0728388 +534 -0.0235752 0.00407866 0.00373027 +535 -0.011585 0.0522432 0.00647843 +536 0.0400312 -0.00904366 0.0126741 +537 -0.0178591 -0.000359808 0.00797485 +538 -0.067167 0.0625514 0.00392853 +539 -0.0596438 0.0779391 0.0290601 +540 0.0013543 0.0302152 0.00901705 +541 0.0168301 0.00522322 0.0737244 +542 0.0174324 0.00448014 0.0738384 +543 -0.0618546 0.0649931 0.00590465 +544 0.0194429 0.0304209 0.00452872 +545 -0.0236633 0.0648084 0.0124456 +546 -0.00249493 -0.0562542 0.012985 +547 -0.0025263 -0.0246783 0.0125409 +548 -0.0396392 0.0718092 0.02876 +549 -0.0158083 -0.0164708 0.00645267 +550 0.016879 0.0245859 0.0055459 +551 -0.0688499 0.0811361 0.0461884 +552 0.0290982 -0.00647478 0.00827907 +553 -0.041817 0.0761358 0.0343691 +554 -0.0642688 0.0653922 0.00517065 +555 -0.0162175 0.00239503 0.00694561 +556 0.00467524 0.0360758 0.00643588 +557 -0.0222973 0.0035638 0.00646752 +558 -0.0708092 0.0801688 0.0482801 +559 -0.0549524 0.0787083 0.0296023 +560 -0.0631054 0.0672415 0.00811831 +561 -0.0155444 -0.0163359 0.0060847 +562 -0.0574097 0.0788047 0.0473507 +563 -0.0558952 0.0591814 0.001764 +564 -0.0177409 0.0619627 0.0144786 +565 -0.00178349 -0.0487397 0.0125937 +566 -0.0111058 0.0522074 0.00829904 +567 -0.0260139 0.00360897 0.00461987 +568 -0.0204566 0.00423454 0.00564674 +569 0.00612936 0.0370467 0.00680554 +570 0.010446 0.0313554 0.00705031 +571 -0.0569353 0.05965 0.00118235 +572 -0.0506685 0.0625792 0.00279292 +573 -0.0249761 0.00485573 0.00443819 +574 0.0172421 0.00725128 0.0738262 +575 -0.0219613 0.0643004 0.0138184 +576 -0.00260185 -0.0513557 0.0142694 +577 -0.0167422 0.00259292 0.00779623 +578 0.00214524 0.0341103 0.00650831 +579 -0.0236765 0.00572293 0.004305 +580 -0.0616879 0.0784644 0.0353636 +581 -0.0125522 0.0533024 0.00573952 +582 -0.00373263 -0.048886 0.014509 +583 -0.00253347 -0.0472982 0.0131992 +584 -0.0128746 -0.017623 0.00940414 +585 -5.43548e-05 0.0393803 0.00728201 +586 -0.0258702 0.00405717 0.00525282 +587 0.0183599 0.0265636 0.00640112 +588 0.0459896 -0.0257989 0.0100883 +589 -0.0295424 0.0680594 0.0247957 +590 -0.0245383 0.0634107 0.0123732 +591 0.0066096 0.0377811 0.00691952 +592 -0.0450015 0.0646553 0.00575343 +593 -0.0622505 0.0661482 0.00839783 +594 -0.0256248 0.0608105 0.0161665 +595 0.017488 0.00853314 0.0720965 +596 -0.0596734 0.0705097 0.00992485 +597 -0.0665798 0.0628689 0.00493615 +598 -0.0624322 0.0664941 0.0080812 +599 0.0436037 -0.00911409 0.00950451 +600 -0.0258241 0.00183578 0.00455937 +601 -0.0702703 0.0796913 0.0546337 +602 -0.027947 0.0630495 0.0231884 +603 -0.0601839 0.0704633 0.0106076 +604 -0.019796 -0.0130118 0.0069497 +605 -0.0183149 0.0630548 0.012418 +606 -0.0302535 0.0701272 0.02364 +607 -0.0574291 0.0790851 0.0314511 +608 -0.0506885 0.0650762 0.00396145 +609 -0.021101 0.0616869 0.0137094 +610 -0.0331684 0.0670427 0.023997 +611 0.0134393 0.00644533 0.00718965 +612 -0.0111807 -0.0194906 0.00818236 +613 -0.0255718 0.00304117 0.00332801 +614 -0.0126697 -0.015488 0.00653208 +615 -0.0247074 0.00660999 0.00551935 +616 0.0173416 0.0031807 0.0727906 +617 0.0172416 0.0236783 0.00588169 +618 0.0190309 0.0293428 0.00437137 +619 0.016715 0.00646681 0.0747173 +620 -0.0362286 0.072292 0.023504 +621 -0.0193589 -0.00042516 0.00470745 +622 -0.0218861 0.0643631 0.0125137 +623 -0.0102557 0.0512168 0.00711881 +624 0.0404202 -0.00631757 0.0116411 +625 0.0462272 -0.00679819 0.0101561 +626 -0.0259792 0.0656558 0.0150971 +627 0.0162732 0.0229634 0.00624384 +628 0.00353474 0.0364474 0.00843339 +629 4.6368e-06 0.0388726 0.00973083 +630 -0.0216501 0.0633078 0.012475 +631 -0.0653553 0.0635995 0.0060088 +632 -0.0129397 0.0533345 0.00604151 +633 -0.00189413 -0.0244631 0.013557 +634 -0.0610974 0.0673557 0.00916116 +635 0.0169636 0.00823874 0.0726305 +636 -0.0262169 0.00566462 0.00486021 +637 -0.00105663 -0.050339 0.013034 +638 -0.0522352 0.0618469 0.00239028 +639 -0.0658611 0.0623674 0.00600767 +640 -0.0308719 0.0671807 0.0240148 +641 -0.0271033 0.0631674 0.0232081 +642 0.000463176 0.0377435 0.00713404 +643 0.0197653 -0.0105149 0.0573133 +644 -0.0261272 0.00574879 0.00514751 +645 -0.0256133 0.00236555 0.00535812 +646 0.0395658 -0.00664927 0.0115095 +647 -0.0346515 0.0704144 0.0260764 +648 -0.0676857 0.0619198 0.00410476 +649 -0.0352382 0.0722683 0.0261851 +650 -0.0489272 0.0632235 0.00329626 +651 -0.0514659 0.0617489 0.00295197 +652 -0.070483 0.0805389 0.0464472 +$EndNodes +$Elements +1654 +2 4 0 227 308 190 188 +3 4 0 203 353 199 163 +4 4 0 331 305 504 150 +5 4 0 142 328 128 138 +6 4 0 490 439 18 571 +7 4 0 364 289 287 414 +8 4 0 296 336 304 298 +9 4 0 564 419 300 381 +10 4 0 398 569 373 591 +11 4 0 486 473 639 422 +12 4 0 338 89 566 489 +13 4 0 332 554 543 424 +14 4 0 80 67 71 302 +15 4 0 149 146 109 108 +16 4 0 98 90 375 342 +17 4 0 341 308 325 313 +18 4 0 147 314 126 116 +19 4 0 124 318 156 131 +20 4 0 245 322 206 308 +21 4 0 348 311 516 186 +22 4 0 135 150 319 151 +23 4 0 147 314 307 311 +24 4 0 464 588 301 528 +25 4 0 461 33 35 333 +26 4 0 196 192 373 314 +27 4 0 108 81 302 122 +28 4 0 366 258 227 357 +29 4 0 511 107 512 353 +30 4 0 146 170 354 172 +31 4 0 297 175 156 130 +32 4 0 130 297 175 308 +33 4 0 318 159 319 195 +34 4 0 154 123 122 342 +35 4 0 261 308 259 260 +36 4 0 132 142 128 318 +37 4 0 241 250 240 205 +38 4 0 226 227 248 324 +39 4 0 575 609 475 49 +40 4 0 375 91 123 90 +41 4 0 260 308 255 251 +42 4 0 517 612 63 482 +43 4 0 120 117 131 297 +44 4 0 318 131 297 156 +45 4 0 147 319 311 307 +46 4 0 131 120 297 130 +47 4 0 120 297 111 117 +48 4 0 308 174 206 360 +49 4 0 148 313 325 175 +50 4 0 148 313 175 174 +51 4 0 302 80 122 81 +52 4 0 107 353 511 110 +53 4 0 322 231 198 197 +54 4 0 61 58 564 57 +55 4 0 240 386 212 221 +56 4 0 121 297 143 117 +57 4 0 121 297 117 111 +58 4 0 307 235 314 182 +59 4 0 307 314 166 182 +60 4 0 417 308 175 316 +61 4 0 308 175 360 417 +62 4 0 601 9 458 1 +63 4 0 459 429 536 599 +64 4 0 211 242 206 308 +65 4 0 528 588 301 356 +66 4 0 316 297 308 175 +67 4 0 197 188 308 228 +68 4 0 231 308 228 197 +69 4 0 231 197 322 308 +70 4 0 188 197 308 361 +71 4 0 322 361 308 197 +72 4 0 259 308 256 255 +73 4 0 298 306 304 299 +74 4 0 302 342 146 122 +75 4 0 251 322 245 308 +76 4 0 298 306 299 236 +77 4 0 342 302 169 129 +78 4 0 157 319 331 150 +79 4 0 190 195 324 227 +80 4 0 146 342 354 154 +81 4 0 190 297 308 324 +82 4 0 236 254 306 299 +83 4 0 354 179 201 322 +84 4 0 308 297 188 361 +85 4 0 361 188 164 297 +86 4 0 195 165 190 318 +87 4 0 307 215 257 235 +88 4 0 194 235 215 307 +89 4 0 174 129 148 313 +90 4 0 169 313 129 174 +91 4 0 322 255 251 201 +92 4 0 366 265 308 258 +93 4 0 227 308 258 366 +94 4 0 258 308 249 265 +95 4 0 227 308 228 258 +96 4 0 448 192 373 196 +97 4 0 228 308 249 258 +98 4 0 296 298 514 336 +99 4 0 125 150 348 126 +100 4 0 125 160 348 150 +101 4 0 244 264 242 316 +102 4 0 264 316 244 271 +103 4 0 224 233 225 219 +104 4 0 107 353 163 199 +105 4 0 217 223 219 225 +106 4 0 308 174 313 206 +107 4 0 206 313 179 174 +108 4 0 241 230 212 233 +109 4 0 241 233 212 218 +110 4 0 267 278 312 273 +111 4 0 267 312 262 273 +112 4 0 206 179 322 245 +113 4 0 242 245 206 308 +114 4 0 144 319 159 157 +115 4 0 265 308 266 272 +116 4 0 218 219 392 233 +117 4 0 264 324 316 271 +118 4 0 324 308 264 316 +119 4 0 297 318 117 131 +120 4 0 128 117 318 124 +121 4 0 354 207 201 177 +122 4 0 207 177 354 184 +123 4 0 155 163 353 203 +124 4 0 131 297 156 130 +125 4 0 395 330 236 202 +126 4 0 164 142 318 190 +127 4 0 253 314 234 311 +128 4 0 307 314 147 166 +129 4 0 331 234 253 254 +130 4 0 306 236 298 331 +131 4 0 156 297 316 175 +132 4 0 324 319 318 316 +133 4 0 297 324 316 308 +134 4 0 373 314 102 125 +135 4 0 167 155 378 192 +136 4 0 278 324 272 269 +137 4 0 278 276 272 324 +138 4 0 319 159 157 336 +139 4 0 267 257 312 243 +140 4 0 307 215 243 257 +141 4 0 156 297 318 316 +142 4 0 207 354 170 184 +143 4 0 124 144 139 156 +144 4 0 267 312 250 243 +145 4 0 144 151 139 319 +146 4 0 318 316 319 144 +147 4 0 316 139 319 144 +148 4 0 139 144 316 156 +149 4 0 316 191 312 319 +150 4 0 316 191 317 156 +151 4 0 313 308 175 174 +152 4 0 253 234 331 311 +153 4 0 331 395 234 236 +154 4 0 272 265 308 366 +155 4 0 103 140 133 510 +156 4 0 235 199 246 314 +157 4 0 246 237 314 199 +158 4 0 144 151 319 157 +159 4 0 92 157 151 144 +160 4 0 92 159 157 144 +161 4 0 395 234 236 330 +162 4 0 395 330 202 348 +163 4 0 348 330 202 209 +164 4 0 324 312 316 271 +165 4 0 266 308 324 272 +166 4 0 324 366 308 227 +167 4 0 242 264 245 308 +168 4 0 272 266 269 324 +169 4 0 135 151 319 139 +170 4 0 40 35 28 29 +171 4 0 88 148 129 342 +172 4 0 325 342 148 88 +173 4 0 314 116 147 166 +174 4 0 77 353 320 94 +175 4 0 331 262 319 306 +176 4 0 319 317 139 316 +177 4 0 450 329 482 328 +178 4 0 183 307 147 166 +179 4 0 188 361 176 197 +180 4 0 169 179 313 174 +181 4 0 314 196 348 373 +182 4 0 102 84 116 353 +183 4 0 102 77 84 353 +184 4 0 191 147 319 317 +185 4 0 307 262 257 312 +186 4 0 307 257 246 235 +187 4 0 307 257 262 246 +188 4 0 128 318 144 124 +189 4 0 246 314 237 253 +190 4 0 314 203 237 234 +191 4 0 142 128 318 138 +192 4 0 253 237 234 314 +193 4 0 306 319 331 336 +194 4 0 307 314 235 246 +195 4 0 316 250 312 191 +196 4 0 450 403 349 329 +197 4 0 121 297 101 143 +198 4 0 382 164 101 297 +199 4 0 369 198 322 193 +200 4 0 264 266 324 269 +201 4 0 322 354 170 207 +202 4 0 322 170 193 207 +203 4 0 353 84 116 110 +204 4 0 70 302 68 83 +205 4 0 331 311 234 395 +206 4 0 323 493 282 301 +207 4 0 269 278 324 271 +208 4 0 278 312 324 271 +209 4 0 207 170 180 184 +210 4 0 207 170 193 180 +211 4 0 325 130 175 308 +212 4 0 146 354 170 154 +213 4 0 354 302 342 146 +214 4 0 161 348 510 181 +215 4 0 182 314 199 235 +216 4 0 322 354 369 170 +217 4 0 231 207 322 198 +218 4 0 313 322 375 341 +219 4 0 375 361 341 322 +220 4 0 322 207 193 198 +221 4 0 297 143 164 101 +222 4 0 221 213 240 232 +223 4 0 190 188 308 297 +224 4 0 341 361 375 382 +225 4 0 341 308 313 322 +226 4 0 134 158 184 354 +227 4 0 247 308 261 249 +228 4 0 263 308 260 251 +229 4 0 318 319 159 144 +230 4 0 309 262 306 319 +231 4 0 250 204 243 312 +232 4 0 448 192 167 378 +233 4 0 37 333 620 35 +234 4 0 37 33 333 35 +235 4 0 297 318 316 324 +236 4 0 167 448 378 153 +237 4 0 212 218 233 219 +238 4 0 88 325 342 494 +239 4 0 246 307 314 253 +240 4 0 307 253 246 262 +241 4 0 126 311 150 348 +242 4 0 388 611 336 514 +243 4 0 348 234 420 314 +244 4 0 236 254 331 306 +245 4 0 348 314 311 234 +246 4 0 211 308 360 417 +247 4 0 373 102 320 125 +248 4 0 316 250 191 438 +249 4 0 250 205 191 438 +250 4 0 254 262 306 309 +251 4 0 254 309 306 310 +252 4 0 299 254 306 310 +253 4 0 331 262 306 254 +254 4 0 292 294 295 293 +255 4 0 194 307 215 204 +256 4 0 304 306 384 299 +257 4 0 267 312 257 262 +258 4 0 353 192 378 155 +259 4 0 319 159 336 195 +260 4 0 353 192 373 378 +261 4 0 336 185 388 195 +262 4 0 312 250 271 267 +263 4 0 271 250 312 316 +264 4 0 261 249 308 265 +265 4 0 268 308 265 261 +266 4 0 247 308 249 228 +267 4 0 227 195 324 226 +268 4 0 366 324 415 337 +269 4 0 337 366 324 357 +270 4 0 190 195 318 324 +271 4 0 156 318 124 144 +272 4 0 263 266 308 264 +273 4 0 251 263 308 264 +274 4 0 197 198 322 369 +275 4 0 154 354 369 342 +276 4 0 188 308 228 227 +277 4 0 79 328 138 92 +278 4 0 316 317 139 156 +279 4 0 360 175 308 174 +280 4 0 255 251 308 322 +281 4 0 255 256 252 308 +282 4 0 247 228 231 308 +283 4 0 247 308 231 256 +284 4 0 134 149 394 354 +285 4 0 83 162 96 302 +286 4 0 161 373 140 348 +287 4 0 88 67 302 68 +288 4 0 302 97 88 68 +289 4 0 512 166 314 182 +290 4 0 420 192 314 234 +291 4 0 348 330 420 234 +292 4 0 192 314 234 203 +293 4 0 91 123 105 115 +294 4 0 394 70 302 81 +295 4 0 309 273 262 319 +296 4 0 319 262 312 273 +297 4 0 67 302 68 70 +298 4 0 271 278 312 267 +299 4 0 66 57 326 58 +300 4 0 188 136 176 361 +301 4 0 157 331 185 504 +302 4 0 136 361 188 164 +303 4 0 244 250 271 316 +304 4 0 71 302 67 70 +305 4 0 244 213 232 240 +306 4 0 81 302 71 70 +307 4 0 354 149 108 146 +308 4 0 314 237 203 199 +309 4 0 506 378 435 629 +310 4 0 244 438 316 213 +311 4 0 97 302 169 162 +312 4 0 244 316 438 250 +313 4 0 313 129 342 169 +314 4 0 382 113 101 164 +315 4 0 506 435 378 94 +316 4 0 91 123 85 105 +317 4 0 308 264 245 251 +318 4 0 242 264 308 316 +319 4 0 450 349 482 329 +320 4 0 314 373 348 125 +321 4 0 92 138 159 144 +322 4 0 395 311 234 348 +323 4 0 278 273 324 312 +324 4 0 373 378 435 320 +325 4 0 147 311 319 135 +326 4 0 126 311 135 150 +327 4 0 126 135 311 147 +328 4 0 314 348 311 126 +329 4 0 83 302 82 70 +330 4 0 378 435 629 373 +331 4 0 195 159 165 318 +332 4 0 316 312 324 319 +333 4 0 156 175 316 387 +334 4 0 336 298 514 331 +335 4 0 88 342 129 302 +336 4 0 319 307 331 311 +337 4 0 253 314 311 307 +338 4 0 311 331 253 307 +339 4 0 297 341 308 130 +340 4 0 314 348 126 125 +341 4 0 147 314 311 126 +342 4 0 61 339 99 338 +343 4 0 250 204 312 191 +344 4 0 305 185 508 331 +345 4 0 211 242 308 316 +346 4 0 211 308 417 316 +347 4 0 213 316 211 417 +348 4 0 214 215 230 204 +349 4 0 244 316 242 211 +350 4 0 244 211 213 316 +351 4 0 465 501 344 502 +352 4 0 108 354 302 394 +353 4 0 313 129 148 342 +354 4 0 337 324 415 248 +355 4 0 337 258 366 357 +356 4 0 121 101 297 111 +357 4 0 382 101 111 297 +358 4 0 157 159 185 336 +359 4 0 226 336 195 324 +360 4 0 307 262 331 253 +361 4 0 307 262 319 331 +362 4 0 331 254 253 262 +363 4 0 248 336 552 296 +364 4 0 319 324 195 336 +365 4 0 248 296 226 336 +366 4 0 324 248 336 552 +367 4 0 147 183 191 307 +368 4 0 282 281 276 323 +369 4 0 281 323 282 301 +370 4 0 109 119 105 122 +371 4 0 297 143 117 318 +372 4 0 109 122 105 80 +373 4 0 308 366 324 272 +374 4 0 297 318 324 190 +375 4 0 297 190 164 318 +376 4 0 214 204 230 212 +377 4 0 224 212 214 230 +378 4 0 297 143 318 164 +379 4 0 264 308 324 266 +380 4 0 264 269 324 271 +381 4 0 132 117 143 318 +382 4 0 130 297 341 120 +383 4 0 341 130 120 98 +384 4 0 277 343 356 279 +385 4 0 325 308 175 313 +386 4 0 109 81 108 122 +387 4 0 109 122 108 146 +388 4 0 348 234 395 330 +389 4 0 341 111 120 297 +390 4 0 341 100 98 120 +391 4 0 341 111 100 120 +392 4 0 226 336 324 248 +393 4 0 318 319 324 195 +394 4 0 275 270 324 309 +395 4 0 309 336 324 319 +396 4 0 552 270 336 324 +397 4 0 273 309 275 324 +398 4 0 403 328 329 450 +399 4 0 382 111 341 297 +400 4 0 361 322 308 341 +401 4 0 361 341 308 297 +402 4 0 342 85 73 90 +403 4 0 342 73 85 80 +404 4 0 323 324 366 276 +405 4 0 361 297 164 382 +406 4 0 96 82 83 302 +407 4 0 45 647 44 42 +408 4 0 179 354 201 177 +409 4 0 53 621 54 347 +410 4 0 117 124 131 318 +411 4 0 156 144 316 318 +412 4 0 369 198 193 141 +413 4 0 342 302 88 67 +414 4 0 67 80 342 302 +415 4 0 73 80 342 67 +416 4 0 342 73 67 76 +417 4 0 372 528 289 285 +418 4 0 285 528 289 287 +419 4 0 355 98 325 494 +420 4 0 122 119 105 123 +421 4 0 394 82 134 302 +422 4 0 494 88 76 342 +423 4 0 109 81 122 80 +424 4 0 447 580 503 505 +425 4 0 114 118 141 145 +426 4 0 311 150 319 135 +427 4 0 108 122 302 146 +428 4 0 204 307 183 194 +429 4 0 191 204 307 183 +430 4 0 382 101 100 111 +431 4 0 382 111 100 341 +432 4 0 318 159 138 144 +433 4 0 588 281 301 356 +434 4 0 87 61 77 57 +435 4 0 318 159 165 138 +436 4 0 7 12 2 486 +437 4 0 316 191 319 317 +438 4 0 208 196 449 445 +439 4 0 322 369 354 313 +440 4 0 354 158 177 162 +441 4 0 354 169 162 179 +442 4 0 313 369 354 342 +443 4 0 179 162 354 177 +444 4 0 130 98 341 355 +445 4 0 325 130 341 355 +446 4 0 337 357 324 248 +447 4 0 324 357 227 248 +448 4 0 588 281 464 301 +449 4 0 375 341 382 98 +450 4 0 454 75 61 155 +451 4 0 353 77 84 74 +452 4 0 331 305 185 504 +453 4 0 311 331 319 150 +454 4 0 378 339 167 106 +455 4 0 318 190 142 165 +456 4 0 138 142 165 318 +457 4 0 18 12 397 14 +458 4 0 298 514 331 513 +459 4 0 118 137 141 168 +460 4 0 298 331 236 395 +461 4 0 395 298 331 513 +462 4 0 93 157 92 159 +463 4 0 354 158 184 177 +464 4 0 151 157 92 93 +465 4 0 78 93 151 92 +466 4 0 378 448 629 153 +467 4 0 102 314 126 125 +468 4 0 126 116 314 102 +469 4 0 61 72 303 75 +470 4 0 39 461 350 553 +471 4 0 350 39 33 461 +472 4 0 311 331 513 395 +473 4 0 311 331 305 509 +474 4 0 353 102 314 116 +475 4 0 204 215 243 307 +476 4 0 106 153 167 378 +477 4 0 97 162 83 302 +478 4 0 107 353 199 512 +479 4 0 297 188 164 190 +480 4 0 147 319 139 135 +481 4 0 77 353 87 74 +482 4 0 353 203 199 314 +483 4 0 512 314 353 199 +484 4 0 37 38 29 35 +485 4 0 485 140 373 125 +486 4 0 398 448 373 196 +487 4 0 196 570 373 398 +488 4 0 324 248 552 415 +489 4 0 415 270 552 324 +490 4 0 52 57 594 564 +491 4 0 285 289 414 287 +492 4 0 438 250 205 240 +493 4 0 524 425 25 17 +494 4 0 29 25 524 425 +495 4 0 87 77 61 353 +496 4 0 93 92 138 159 +497 4 0 93 92 79 138 +498 4 0 203 192 353 155 +499 4 0 192 353 314 203 +500 4 0 88 302 129 97 +501 4 0 169 342 354 302 +502 4 0 147 319 317 139 +503 4 0 435 426 629 373 +504 4 0 197 168 369 176 +505 4 0 369 176 361 197 +506 4 0 157 151 319 150 +507 4 0 307 319 312 191 +508 4 0 312 307 191 204 +509 4 0 628 373 441 374 +510 4 0 513 331 311 509 +511 4 0 49 594 413 46 +512 4 0 303 163 87 61 +513 4 0 146 342 154 122 +514 4 0 274 366 415 337 +515 4 0 274 258 366 337 +516 4 0 87 57 74 66 +517 4 0 304 306 336 384 +518 4 0 204 250 205 191 +519 4 0 110 74 66 87 +520 4 0 163 87 61 353 +521 4 0 204 205 250 241 +522 4 0 387 438 213 316 +523 4 0 150 160 348 311 +524 4 0 313 369 342 375 +525 4 0 313 322 369 375 +526 4 0 97 129 169 302 +527 4 0 504 305 393 150 +528 4 0 181 348 500 187 +529 4 0 610 527 42 44 +530 4 0 44 527 42 620 +531 4 0 311 305 456 509 +532 4 0 311 509 456 516 +533 4 0 365 512 166 116 +534 4 0 116 512 166 314 +535 4 0 509 305 508 331 +536 4 0 322 369 193 170 +537 4 0 535 526 581 632 +538 4 0 182 314 512 199 +539 4 0 497 441 373 540 +540 4 0 37 42 46 527 +541 4 0 500 209 187 348 +542 4 0 312 257 307 243 +543 4 0 323 366 281 276 +544 4 0 348 420 209 196 +545 4 0 366 279 276 272 +546 4 0 202 500 186 348 +547 4 0 386 406 221 232 +548 4 0 64 526 62 489 +549 4 0 336 159 185 195 +550 4 0 404 24 559 335 +551 4 0 404 24 607 559 +552 4 0 384 336 552 270 +553 4 0 244 240 438 213 +554 4 0 244 438 240 250 +555 4 0 430 461 620 333 +556 4 0 461 333 35 620 +557 4 0 61 564 64 334 +558 4 0 381 437 47 413 +559 4 0 279 277 265 258 +560 4 0 279 277 258 274 +561 4 0 186 500 181 348 +562 4 0 140 510 348 160 +563 4 0 377 410 36 350 +564 4 0 202 330 236 209 +565 4 0 380 345 614 468 +566 4 0 99 339 378 106 +567 4 0 378 106 418 99 +568 4 0 378 448 373 629 +569 4 0 194 235 307 182 +570 4 0 194 307 166 182 +571 4 0 194 307 183 166 +572 4 0 353 373 320 378 +573 4 0 68 97 83 302 +574 4 0 347 496 604 476 +575 4 0 161 181 411 373 +576 4 0 570 374 400 368 +577 4 0 40 38 35 29 +578 4 0 364 289 327 528 +579 4 0 324 309 319 273 +580 4 0 353 378 320 94 +581 4 0 358 91 471 375 +582 4 0 134 394 302 354 +583 4 0 394 149 108 354 +584 4 0 172 354 146 149 +585 4 0 382 358 471 375 +586 4 0 101 382 90 358 +587 4 0 651 346 638 390 +588 4 0 382 90 100 101 +589 4 0 334 594 564 475 +590 4 0 369 361 375 322 +591 4 0 322 197 369 361 +592 4 0 342 325 98 494 +593 4 0 325 313 148 342 +594 4 0 342 325 375 98 +595 4 0 115 369 123 367 +596 4 0 342 98 76 494 +597 4 0 369 375 576 115 +598 4 0 353 512 116 314 +599 4 0 336 304 552 296 +600 4 0 336 306 304 298 +601 4 0 226 514 336 296 +602 4 0 108 302 81 394 +603 4 0 181 411 373 374 +604 4 0 26 440 571 383 +605 4 0 26 383 346 440 +606 4 0 211 360 308 206 +607 4 0 87 74 57 77 +608 4 0 358 113 101 382 +609 4 0 195 388 336 226 +610 4 0 241 233 218 238 +611 4 0 155 339 378 353 +612 4 0 345 79 468 476 +613 4 0 213 316 417 175 +614 4 0 387 316 213 175 +615 4 0 312 307 262 319 +616 4 0 435 485 426 373 +617 4 0 435 373 125 485 +618 4 0 299 310 306 384 +619 4 0 26 425 25 34 +620 4 0 118 114 367 434 +621 4 0 26 34 25 608 +622 4 0 223 222 529 392 +623 4 0 527 38 37 35 +624 4 0 37 527 46 38 +625 4 0 342 123 90 375 +626 4 0 342 123 85 90 +627 4 0 335 350 33 35 +628 4 0 350 461 33 35 +629 4 0 85 91 90 123 +630 4 0 259 247 308 261 +631 4 0 629 628 448 373 +632 4 0 633 142 328 128 +633 4 0 629 497 628 373 +634 4 0 303 61 87 72 +635 4 0 236 254 234 331 +636 4 0 341 98 325 355 +637 4 0 373 570 400 569 +638 4 0 398 570 373 569 +639 4 0 49 413 527 46 +640 4 0 49 46 527 457 +641 4 0 49 626 48 527 +642 4 0 241 204 243 250 +643 4 0 49 527 48 457 +644 4 0 392 218 233 238 +645 4 0 233 392 238 223 +646 4 0 178 198 197 141 +647 4 0 198 197 141 369 +648 4 0 364 290 287 528 +649 4 0 419 381 564 413 +650 4 0 92 78 79 59 +651 4 0 192 373 314 353 +652 4 0 386 406 238 423 +653 4 0 367 369 137 391 +654 4 0 437 413 419 606 +655 4 0 413 437 47 606 +656 4 0 239 252 322 255 +657 4 0 454 61 339 155 +658 4 0 34 466 425 29 +659 4 0 221 386 232 240 +660 4 0 60 64 489 484 +661 4 0 484 65 60 64 +662 4 0 212 386 218 221 +663 4 0 241 240 386 212 +664 4 0 241 205 240 212 +665 4 0 607 24 16 470 +666 4 0 620 42 37 527 +667 4 0 37 333 42 620 +668 4 0 95 87 66 69 +669 4 0 113 164 382 361 +670 4 0 410 30 432 21 +671 4 0 371 1 522 458 +672 4 0 527 47 43 40 +673 4 0 596 425 17 15 +674 4 0 393 456 160 311 +675 4 0 110 95 87 66 +676 4 0 160 311 456 516 +677 4 0 512 511 365 166 +678 4 0 353 511 365 512 +679 4 0 128 144 318 138 +680 4 0 341 130 325 308 +681 4 0 87 61 57 58 +682 4 0 419 58 564 72 +683 4 0 414 289 327 364 +684 4 0 320 378 435 94 +685 4 0 364 528 287 289 +686 4 0 212 221 205 240 +687 4 0 134 172 149 354 +688 4 0 134 172 354 184 +689 4 0 319 147 191 307 +690 4 0 589 641 606 436 +691 4 0 347 79 59 476 +692 4 0 345 79 476 92 +693 4 0 92 138 144 328 +694 4 0 86 92 144 328 +695 4 0 32 399 34 38 +696 4 0 306 309 336 310 +697 4 0 347 604 468 476 +698 4 0 347 468 79 476 +699 4 0 614 345 79 468 +700 4 0 384 310 336 270 +701 4 0 439 25 26 422 +702 4 0 196 192 314 420 +703 4 0 348 420 196 314 +704 4 0 132 143 142 318 +705 4 0 164 142 143 318 +706 4 0 386 406 423 221 +707 4 0 35 527 38 40 +708 4 0 158 354 96 162 +709 4 0 169 302 354 162 +710 4 0 334 475 564 363 +711 4 0 155 61 303 75 +712 4 0 94 353 378 339 +713 4 0 224 233 219 212 +714 4 0 214 215 204 194 +715 4 0 204 243 230 241 +716 4 0 204 230 212 241 +717 4 0 391 474 369 136 +718 4 0 286 588 528 356 +719 4 0 35 620 527 47 +720 4 0 136 474 361 565 +721 4 0 566 526 632 64 +722 4 0 490 439 11 14 +723 4 0 209 330 420 348 +724 4 0 35 527 40 47 +725 4 0 76 342 73 98 +726 4 0 77 353 102 320 +727 4 0 268 308 261 260 +728 4 0 167 155 339 378 +729 4 0 465 289 385 344 +730 4 0 255 308 260 259 +731 4 0 335 24 470 33 +732 4 0 559 24 470 335 +733 4 0 522 1 371 428 +734 4 0 347 53 496 54 +735 4 0 559 24 607 470 +736 4 0 476 347 496 54 +737 4 0 312 204 243 307 +738 4 0 230 215 243 204 +739 4 0 241 218 212 386 +740 4 0 241 238 218 386 +741 4 0 29 33 28 23 +742 4 0 23 335 559 470 +743 4 0 297 382 361 341 +744 4 0 336 611 185 331 +745 4 0 388 185 336 611 +746 4 0 353 373 102 320 +747 4 0 373 102 314 353 +748 4 0 44 527 606 610 +749 4 0 74 110 84 353 +750 4 0 610 527 606 413 +751 4 0 325 341 375 98 +752 4 0 369 136 137 391 +753 4 0 169 354 342 313 +754 4 0 274 366 279 281 +755 4 0 281 366 279 276 +756 4 0 322 313 206 308 +757 4 0 414 289 344 385 +758 4 0 114 546 367 434 +759 4 0 367 391 434 369 +760 4 0 155 163 303 61 +761 4 0 47 620 527 44 +762 4 0 384 304 552 336 +763 4 0 384 310 306 336 +764 4 0 99 378 339 94 +765 4 0 506 94 378 99 +766 4 0 365 353 512 116 +767 4 0 378 99 418 506 +768 4 0 478 23 559 470 +769 4 0 328 86 633 128 +770 4 0 265 308 268 266 +771 4 0 268 308 263 266 +772 4 0 564 419 436 58 +773 4 0 460 75 564 65 +774 4 0 339 61 99 94 +775 4 0 518 564 65 460 +776 4 0 643 216 229 392 +777 4 0 342 88 76 67 +778 4 0 26 422 11 439 +779 4 0 26 440 439 571 +780 4 0 411 161 373 441 +781 4 0 442 467 412 10 +782 4 0 350 377 24 33 +783 4 0 225 409 217 223 +784 4 0 410 377 24 350 +785 4 0 24 350 33 335 +786 4 0 371 522 523 458 +787 4 0 278 324 273 276 +788 4 0 273 324 275 276 +789 4 0 170 354 172 184 +790 4 0 169 179 354 313 +791 4 0 607 16 24 580 +792 4 0 367 391 137 118 +793 4 0 35 620 37 527 +794 4 0 548 33 461 333 +795 4 0 414 385 344 294 +796 4 0 414 289 288 344 +797 4 0 65 64 484 454 +798 4 0 93 79 78 401 +799 4 0 375 382 358 90 +800 4 0 413 575 564 594 +801 4 0 187 181 368 189 +802 4 0 358 375 90 91 +803 4 0 275 276 324 323 +804 4 0 493 270 323 275 +805 4 0 532 323 276 275 +806 4 0 324 270 323 415 +807 4 0 275 323 324 270 +808 4 0 157 331 319 336 +809 4 0 454 339 61 338 +810 4 0 527 47 507 43 +811 4 0 74 87 110 353 +812 4 0 61 353 339 155 +813 4 0 444 445 618 379 +814 4 0 173 133 160 510 +815 4 0 352 604 468 347 +816 4 0 161 181 373 348 +817 4 0 23 335 470 33 +818 4 0 181 187 374 373 +819 4 0 29 35 28 33 +820 4 0 348 187 181 373 +821 4 0 562 10 412 447 +822 4 0 10 580 503 447 +823 4 0 399 351 34 38 +824 4 0 515 592 399 32 +825 4 0 434 112 637 474 +826 4 0 134 82 96 302 +827 4 0 224 230 233 212 +828 4 0 134 302 96 354 +829 4 0 302 354 162 96 +830 4 0 376 64 60 564 +831 4 0 606 640 589 45 +832 4 0 369 137 168 141 +833 4 0 113 361 583 136 +834 4 0 197 369 168 141 +835 4 0 12 7 4 14 +836 4 0 510 181 173 171 +837 4 0 61 339 353 94 +838 4 0 369 154 170 354 +839 4 0 404 607 24 21 +840 4 0 411 374 578 441 +841 4 0 500 186 189 480 +842 4 0 535 526 632 566 +843 4 0 628 441 497 483 +844 4 0 478 23 28 559 +845 4 0 28 335 559 23 +846 4 0 93 92 78 79 +847 4 0 554 473 631 453 +848 4 0 198 178 193 141 +849 4 0 187 444 209 500 +850 4 0 226 388 336 514 +851 4 0 287 464 285 528 +852 4 0 528 301 285 372 +853 4 0 497 629 426 373 +854 4 0 394 302 70 82 +855 4 0 64 61 454 75 +856 4 0 444 587 618 445 +857 4 0 467 458 371 523 +858 4 0 371 523 520 467 +859 4 0 371 520 551 467 +860 4 0 385 465 294 292 +861 4 0 468 604 345 476 +862 4 0 584 517 63 345 +863 4 0 176 136 137 369 +864 4 0 439 440 18 571 +865 4 0 490 26 11 439 +866 4 0 324 366 227 357 +867 4 0 606 413 419 436 +868 4 0 527 48 477 507 +869 4 0 527 477 48 457 +870 4 0 527 492 48 507 +871 4 0 527 626 48 492 +872 4 0 134 354 96 158 +873 4 0 62 64 489 60 +874 4 0 52 57 370 594 +875 4 0 326 52 55 564 +876 4 0 524 425 17 19 +877 4 0 373 441 161 540 +878 4 0 373 161 140 540 +879 4 0 66 326 55 58 +880 4 0 58 326 55 564 +881 4 0 310 309 336 270 +882 4 0 324 270 336 309 +883 4 0 157 336 185 331 +884 4 0 181 411 171 161 +885 4 0 640 589 641 606 +886 4 0 537 557 621 54 +887 4 0 282 285 340 288 +888 4 0 372 285 288 340 +889 4 0 382 100 98 341 +890 4 0 502 294 465 292 +891 4 0 43 34 351 38 +892 4 0 221 240 213 205 +893 4 0 438 240 205 213 +894 4 0 425 466 524 29 +895 4 0 354 302 146 108 +896 4 0 435 426 506 629 +897 4 0 497 506 426 629 +898 4 0 187 181 374 368 +899 4 0 517 79 614 345 +900 4 0 342 90 73 98 +901 4 0 180 141 178 152 +902 4 0 178 152 141 168 +903 4 0 193 180 141 178 +904 4 0 140 161 348 510 +905 4 0 9 442 13 362 +906 4 0 442 9 13 467 +907 4 0 408 505 503 580 +908 4 0 607 580 408 16 +909 4 0 327 289 414 385 +910 4 0 372 284 283 340 +911 4 0 359 89 526 566 +912 4 0 607 539 478 470 +913 4 0 140 373 125 348 +914 4 0 328 86 92 517 +915 4 0 527 47 44 606 +916 4 0 155 163 61 353 +917 4 0 367 391 118 434 +918 4 0 338 64 61 454 +919 4 0 64 338 484 454 +920 4 0 359 89 566 338 +921 4 0 489 526 566 64 +922 4 0 448 192 378 373 +923 4 0 350 39 377 33 +924 4 0 369 137 176 168 +925 4 0 377 350 553 39 +926 4 0 325 313 375 341 +927 4 0 340 288 625 282 +928 4 0 342 313 375 325 +929 4 0 524 466 19 20 +930 4 0 425 466 19 524 +931 4 0 348 395 186 202 +932 4 0 610 44 42 45 +933 4 0 409 433 217 223 +934 4 0 217 433 529 223 +935 4 0 582 375 471 115 +936 4 0 434 474 637 369 +937 4 0 382 375 471 582 +938 4 0 98 90 382 375 +939 4 0 382 100 90 98 +940 4 0 123 105 122 85 +941 4 0 122 85 105 80 +942 4 0 43 40 34 38 +943 4 0 369 474 361 136 +944 4 0 469 452 564 460 +945 4 0 46 41 527 457 +946 4 0 415 366 274 323 +947 4 0 191 387 316 438 +948 4 0 191 387 156 316 +949 4 0 434 391 474 369 +950 4 0 502 294 344 465 +951 4 0 502 294 292 293 +952 4 0 476 59 92 79 +953 4 0 306 309 319 336 +954 4 0 528 301 464 285 +955 4 0 301 282 464 285 +956 4 0 208 449 210 379 +957 4 0 210 379 220 208 +958 4 0 551 520 10 467 +959 4 0 359 89 339 106 +960 4 0 110 353 365 116 +961 4 0 353 511 110 365 +962 4 0 118 141 145 152 +963 4 0 34 28 466 29 +964 4 0 621 347 59 54 +965 4 0 59 621 79 347 +966 4 0 342 80 122 302 +967 4 0 369 123 154 342 +968 4 0 123 85 122 342 +969 4 0 122 342 85 80 +970 4 0 450 349 612 482 +971 4 0 564 55 436 413 +972 4 0 40 38 29 34 +973 4 0 606 641 413 436 +974 4 0 28 35 335 33 +975 4 0 34 25 32 29 +976 4 0 487 548 495 479 +977 4 0 187 209 196 348 +978 4 0 461 479 430 495 +979 4 0 311 513 509 186 +980 4 0 395 311 348 186 +981 4 0 187 196 209 444 +982 4 0 485 540 426 373 +983 4 0 21 580 24 447 +984 4 0 412 447 21 562 +985 4 0 412 562 21 446 +986 4 0 447 580 24 10 +987 4 0 46 527 610 413 +988 4 0 229 392 216 222 +989 4 0 323 281 366 274 +990 4 0 281 301 274 323 +991 4 0 599 625 429 282 +992 4 0 608 25 32 34 +993 4 0 372 288 284 340 +994 4 0 227 324 190 308 +995 4 0 373 196 348 187 +996 4 0 425 25 34 29 +997 4 0 628 448 373 591 +998 4 0 591 448 373 398 +999 4 0 477 43 41 527 +1000 4 0 80 71 81 302 +1001 4 0 457 477 41 527 +1002 4 0 647 487 430 479 +1003 4 0 628 373 497 441 +1004 4 0 578 628 441 374 +1005 4 0 410 24 335 350 +1006 4 0 393 311 160 150 +1007 4 0 367 118 137 141 +1008 4 0 343 488 356 396 +1009 4 0 87 72 61 58 +1010 4 0 488 588 356 396 +1011 4 0 476 54 59 347 +1012 4 0 94 353 61 77 +1013 4 0 110 353 87 107 +1014 4 0 251 245 322 201 +1015 4 0 245 179 322 201 +1016 4 0 11 422 486 14 +1017 4 0 287 588 464 528 +1018 4 0 10 467 412 551 +1019 4 0 13 551 412 467 +1020 4 0 371 467 551 13 +1021 4 0 551 10 8 412 +1022 4 0 113 164 361 136 +1023 4 0 425 25 15 26 +1024 4 0 140 348 125 160 +1025 4 0 451 588 528 286 +1026 4 0 180 152 145 141 +1027 4 0 607 16 539 470 +1028 4 0 374 570 400 373 +1029 4 0 373 374 556 400 +1030 4 0 374 373 556 628 +1031 4 0 441 628 578 483 +1032 4 0 497 642 418 629 +1033 4 0 167 89 106 339 +1034 4 0 346 440 390 521 +1035 4 0 369 123 342 375 +1036 4 0 583 382 498 361 +1037 4 0 564 75 72 61 +1038 4 0 564 61 64 75 +1039 4 0 345 517 79 92 +1040 4 0 533 529 223 222 +1041 4 0 498 582 576 375 +1042 4 0 575 376 609 49 +1043 4 0 412 10 8 447 +1044 4 0 561 472 549 468 +1045 4 0 239 322 252 231 +1046 4 0 397 12 4 14 +1047 4 0 367 369 434 576 +1048 4 0 206 313 322 179 +1049 4 0 322 179 313 354 +1050 4 0 12 2 4 7 +1051 4 0 346 638 26 608 +1052 4 0 66 87 57 58 +1053 4 0 72 58 564 61 +1054 4 0 322 207 231 239 +1055 4 0 201 354 322 207 +1056 4 0 239 255 322 201 +1057 4 0 533 402 529 222 +1058 4 0 60 518 564 65 +1059 4 0 11 486 12 14 +1060 4 0 118 168 141 152 +1061 4 0 60 376 564 518 +1062 4 0 576 375 582 115 +1063 4 0 515 34 399 351 +1064 4 0 334 564 64 363 +1065 4 0 311 331 150 305 +1066 4 0 473 538 597 519 +1067 4 0 564 594 575 475 +1068 4 0 36 30 432 410 +1069 4 0 343 396 356 279 +1070 4 0 281 279 356 396 +1071 4 0 281 274 301 356 +1072 4 0 486 7 14 422 +1073 4 0 642 153 585 629 +1074 4 0 153 642 628 629 +1075 4 0 503 447 8 10 +1076 4 0 461 430 620 416 +1077 4 0 493 270 275 280 +1078 4 0 275 493 532 323 +1079 4 0 532 493 282 323 +1080 4 0 461 495 430 416 +1081 4 0 493 532 280 275 +1082 4 0 389 381 47 413 +1083 4 0 49 413 626 527 +1084 4 0 500 189 186 181 +1085 4 0 498 382 582 375 +1086 4 0 410 30 24 377 +1087 4 0 30 410 36 377 +1088 4 0 366 265 279 272 +1089 4 0 608 34 32 31 +1090 4 0 527 40 43 38 +1091 4 0 46 527 41 38 +1092 4 0 43 527 38 41 +1093 4 0 597 639 7 486 +1094 4 0 306 298 336 331 +1095 4 0 11 26 15 543 +1096 4 0 554 11 15 543 +1097 4 0 416 430 620 649 +1098 4 0 291 290 364 327 +1099 4 0 637 498 375 361 +1100 4 0 39 548 33 461 +1101 4 0 422 634 25 543 +1102 4 0 583 582 382 113 +1103 4 0 367 114 118 141 +1104 4 0 473 422 11 554 +1105 4 0 178 197 168 141 +1106 4 0 375 369 123 115 +1107 4 0 91 123 115 375 +1108 4 0 377 350 36 553 +1109 4 0 173 181 516 186 +1110 4 0 110 95 107 87 +1111 4 0 353 107 163 87 +1112 4 0 46 527 42 610 +1113 4 0 500 209 348 202 +1114 4 0 334 61 564 57 +1115 4 0 510 103 140 161 +1116 4 0 160 104 140 133 +1117 4 0 486 11 473 422 +1118 4 0 336 611 331 514 +1119 4 0 576 434 637 369 +1120 4 0 29 466 524 20 +1121 4 0 366 279 265 258 +1122 4 0 366 279 258 274 +1123 4 0 89 484 338 454 +1124 4 0 462 621 568 534 +1125 4 0 133 104 140 103 +1126 4 0 462 534 568 531 +1127 4 0 521 440 390 563 +1128 4 0 383 440 563 390 +1129 4 0 141 154 170 369 +1130 4 0 141 193 369 170 +1131 4 0 173 181 510 516 +1132 4 0 348 510 181 516 +1133 4 0 324 366 276 272 +1134 4 0 415 324 366 323 +1135 4 0 477 527 507 43 +1136 4 0 26 25 440 346 +1137 4 0 430 333 42 479 +1138 4 0 460 452 564 75 +1139 4 0 31 515 32 592 +1140 4 0 181 189 187 500 +1141 4 0 389 527 413 47 +1142 4 0 413 389 626 527 +1143 4 0 376 590 49 575 +1144 4 0 331 611 185 508 +1145 4 0 223 392 407 219 +1146 4 0 223 233 392 219 +1147 4 0 538 648 597 519 +1148 4 0 597 648 538 486 +1149 4 0 557 537 568 499 +1150 4 0 553 39 461 416 +1151 4 0 290 528 451 287 +1152 4 0 554 453 332 560 +1153 4 0 601 467 458 9 +1154 4 0 623 525 535 566 +1155 4 0 566 525 535 526 +1156 4 0 378 106 431 418 +1157 4 0 53 496 352 347 +1158 4 0 564 300 419 72 +1159 4 0 564 452 300 72 +1160 4 0 2 6 7 486 +1161 4 0 421 451 528 286 +1162 4 0 451 528 588 287 +1163 4 0 409 595 433 491 +1164 4 0 79 621 78 401 +1165 4 0 401 621 78 555 +1166 4 0 78 537 555 621 +1167 4 0 599 340 282 301 +1168 4 0 493 599 282 301 +1169 4 0 430 620 42 333 +1170 4 0 565 498 112 637 +1171 4 0 583 498 112 565 +1172 4 0 599 429 536 282 +1173 4 0 599 625 459 429 +1174 4 0 543 554 332 15 +1175 4 0 474 112 637 565 +1176 4 0 364 290 528 327 +1177 4 0 548 461 479 333 +1178 4 0 461 333 430 479 +1179 4 0 383 390 346 440 +1180 4 0 65 60 64 564 +1181 4 0 65 64 75 564 +1182 4 0 383 638 346 390 +1183 4 0 380 468 614 549 +1184 4 0 532 282 276 323 +1185 4 0 157 331 504 150 +1186 4 0 89 454 338 339 +1187 4 0 167 454 89 339 +1188 4 0 8 5 10 551 +1189 4 0 5 520 10 551 +1190 4 0 492 626 545 389 +1191 4 0 389 626 545 469 +1192 4 0 37 33 35 29 +1193 4 0 615 568 499 557 +1194 4 0 500 186 480 202 +1195 4 0 54 56 53 496 +1196 4 0 294 295 291 385 +1197 4 0 295 291 385 327 +1198 4 0 295 294 292 385 +1199 4 0 474 637 361 565 +1200 4 0 497 373 426 540 +1201 4 0 40 29 28 34 +1202 4 0 535 525 581 526 +1203 4 0 328 92 79 517 +1204 4 0 496 56 352 604 +1205 4 0 459 536 646 493 +1206 4 0 459 429 624 536 +1207 4 0 493 536 280 532 +1208 4 0 25 346 26 608 +1209 4 0 351 399 41 38 +1210 4 0 43 41 38 351 +1211 4 0 527 413 47 606 +1212 4 0 308 252 322 231 +1213 4 0 308 255 322 252 +1214 4 0 256 231 252 308 +1215 4 0 256 308 259 247 +1216 4 0 21 30 24 410 +1217 4 0 21 30 562 24 +1218 4 0 315 621 555 568 +1219 4 0 217 219 223 407 +1220 4 0 225 223 219 233 +1221 4 0 407 217 529 223 +1222 4 0 381 452 300 564 +1223 4 0 595 635 433 491 +1224 4 0 414 385 291 327 +1225 4 0 416 39 461 495 +1226 4 0 461 39 548 495 +1227 4 0 461 548 479 495 +1228 4 0 301 282 281 464 +1229 4 0 301 282 285 340 +1230 4 0 315 621 568 462 +1231 4 0 372 289 288 285 +1232 4 0 289 288 285 414 +1233 4 0 431 153 106 378 +1234 4 0 55 641 589 436 +1235 4 0 651 572 638 608 +1236 4 0 564 452 72 75 +1237 4 0 573 534 567 613 +1238 4 0 567 645 600 534 +1239 4 0 499 568 577 537 +1240 4 0 414 327 291 364 +1241 4 0 561 549 614 468 +1242 4 0 338 489 566 64 +1243 4 0 89 484 489 338 +1244 4 0 385 294 465 344 +1245 4 0 445 196 444 209 +1246 4 0 209 550 444 427 +1247 4 0 490 14 11 12 +1248 4 0 490 18 14 12 +1249 4 0 597 648 486 7 +1250 4 0 486 639 7 422 +1251 4 0 639 473 597 631 +1252 4 0 529 491 616 533 +1253 4 0 435 320 125 373 +1254 4 0 616 491 529 541 +1255 4 0 497 628 642 629 +1256 4 0 46 52 413 602 +1257 4 0 623 359 566 338 +1258 4 0 497 506 629 418 +1259 4 0 99 359 623 338 +1260 4 0 65 64 454 75 +1261 4 0 209 617 550 427 +1262 4 0 86 328 144 128 +1263 4 0 570 187 374 368 +1264 4 0 403 86 633 328 +1265 4 0 601 522 458 523 +1266 4 0 604 352 472 56 +1267 4 0 273 312 319 324 +1268 4 0 380 614 63 549 +1269 4 0 561 549 63 614 +1270 4 0 623 525 566 359 +1271 4 0 359 525 566 526 +1272 4 0 566 89 526 489 +1273 4 0 113 382 358 471 +1274 4 0 582 471 382 113 +1275 4 0 523 467 458 601 +1276 4 0 268 308 260 263 +1277 4 0 374 628 556 578 +1278 4 0 498 582 382 583 +1279 4 0 586 645 534 557 +1280 4 0 361 176 369 136 +1281 4 0 277 356 274 279 +1282 4 0 576 637 375 369 +1283 4 0 637 375 369 361 +1284 4 0 373 556 569 400 +1285 4 0 556 373 569 628 +1286 4 0 447 562 24 21 +1287 4 0 47 492 527 507 +1288 4 0 495 39 548 487 +1289 4 0 572 608 651 650 +1290 4 0 541 619 542 574 +1291 4 0 27 562 21 30 +1292 4 0 21 446 562 27 +1293 4 0 517 328 614 79 +1294 4 0 545 530 622 575 +1295 4 0 522 371 523 558 +1296 4 0 523 371 520 558 +1297 4 0 471 91 115 375 +1298 4 0 578 127 628 556 +1299 4 0 127 153 628 556 +1300 4 0 641 413 55 52 +1301 4 0 55 564 436 58 +1302 4 0 564 334 57 594 +1303 4 0 55 641 436 413 +1304 4 0 575 413 49 594 +1305 4 0 15 17 596 560 +1306 4 0 521 440 563 571 +1307 4 0 632 581 62 526 +1308 4 0 285 372 301 340 +1309 4 0 290 451 528 421 +1310 4 0 326 57 564 58 +1311 4 0 205 212 241 204 +1312 4 0 564 452 469 381 +1313 4 0 239 322 207 201 +1314 4 0 223 392 529 407 +1315 4 0 381 564 413 469 +1316 4 0 395 513 311 186 +1317 4 0 389 469 413 626 +1318 4 0 136 361 583 565 +1319 4 0 586 645 567 534 +1320 4 0 32 25 608 346 +1321 4 0 369 367 137 141 +1322 4 0 469 575 545 622 +1323 4 0 593 543 634 422 +1324 4 0 373 569 628 591 +1325 4 0 556 569 153 628 +1326 4 0 196 187 373 570 +1327 4 0 167 454 339 155 +1328 4 0 590 626 575 530 +1329 4 0 536 493 282 532 +1330 4 0 133 140 160 510 +1331 4 0 376 363 64 564 +1332 4 0 209 427 444 587 +1333 4 0 571 440 563 383 +1334 4 0 498 375 576 637 +1335 4 0 531 534 568 579 +1336 4 0 534 568 557 621 +1337 4 0 218 392 643 238 +1338 4 0 568 555 577 537 +1339 4 0 475 609 363 49 +1340 4 0 363 609 475 564 +1341 4 0 393 311 150 305 +1342 4 0 19 425 17 596 +1343 4 0 596 17 603 560 +1344 4 0 522 428 371 558 +1345 4 0 127 628 497 483 +1346 4 0 492 48 545 626 +1347 4 0 21 607 24 580 +1348 4 0 132 117 318 128 +1349 4 0 633 132 547 142 +1350 4 0 437 381 419 413 +1351 4 0 419 381 437 300 +1352 4 0 173 181 186 171 +1353 4 0 405 613 600 534 +1354 4 0 632 526 62 64 +1355 4 0 489 484 64 338 +1356 4 0 600 54 53 621 +1357 4 0 29 20 28 466 +1358 4 0 20 28 466 443 +1359 4 0 49 48 626 590 +1360 4 0 63 345 614 380 +1361 4 0 584 345 63 380 +1362 4 0 470 607 559 478 +1363 4 0 28 23 22 20 +1364 4 0 478 23 22 28 +1365 4 0 473 422 554 631 +1366 4 0 555 537 568 621 +1367 4 0 18 490 14 439 +1368 4 0 596 17 19 603 +1369 4 0 571 440 18 521 +1370 4 0 542 491 616 541 +1371 4 0 534 568 615 557 +1372 4 0 534 568 579 615 +1373 4 0 392 222 229 238 +1374 4 0 626 48 530 590 +1375 4 0 238 406 229 423 +1376 4 0 629 585 642 418 +1377 4 0 418 506 629 378 +1378 4 0 378 431 629 418 +1379 4 0 153 448 628 591 +1380 4 0 591 569 628 153 +1381 4 0 550 209 500 627 +1382 4 0 515 31 32 34 +1383 4 0 209 627 550 617 +1384 4 0 569 556 153 400 +1385 4 0 645 621 557 54 +1386 4 0 529 491 533 223 +1387 4 0 601 1 458 522 +1388 4 0 522 601 1 3 +1389 4 0 359 339 99 106 +1390 4 0 338 99 359 339 +1391 4 0 49 575 626 413 +1392 4 0 473 597 631 453 +1393 4 0 605 564 518 460 +1394 4 0 222 392 402 529 +1395 4 0 113 382 583 361 +1396 4 0 33 335 28 23 +1397 4 0 370 52 594 46 +1398 4 0 408 505 580 607 +1399 4 0 413 640 602 641 +1400 4 0 630 376 564 609 +1401 4 0 49 376 609 363 +1402 4 0 363 376 609 564 +1403 4 0 393 456 311 305 +1404 4 0 218 221 386 643 +1405 4 0 643 386 423 221 +1406 4 0 141 123 369 367 +1407 4 0 498 382 375 361 +1408 4 0 474 637 369 361 +1409 4 0 558 371 520 551 +1410 4 0 558 428 371 551 +1411 4 0 374 441 411 373 +1412 4 0 422 25 26 543 +1413 4 0 25 17 15 634 +1414 4 0 606 44 610 45 +1415 4 0 367 115 369 576 +1416 4 0 367 576 546 115 +1417 4 0 636 573 567 613 +1418 4 0 615 51 579 573 +1419 4 0 50 51 615 636 +1420 4 0 55 413 564 52 +1421 4 0 594 52 413 46 +1422 4 0 564 326 52 57 +1423 4 0 367 434 546 576 +1424 4 0 208 449 379 445 +1425 4 0 379 445 544 208 +1426 4 0 26 439 440 25 +1427 4 0 622 575 605 469 +1428 4 0 636 586 567 573 +1429 4 0 573 586 567 534 +1430 4 0 599 625 340 283 +1431 4 0 605 630 518 564 +1432 4 0 171 510 181 161 +1433 4 0 32 29 38 34 +1434 4 0 402 216 392 222 +1435 4 0 223 222 392 238 +1436 4 0 389 492 527 47 +1437 4 0 389 492 626 527 +1438 4 0 577 555 78 537 +1439 4 0 315 621 401 555 +1440 4 0 15 598 634 560 +1441 4 0 634 17 15 560 +1442 4 0 481 142 328 633 +1443 4 0 128 328 144 138 +1444 4 0 413 610 640 606 +1445 4 0 640 606 610 45 +1446 4 0 379 449 444 445 +1447 4 0 187 449 196 444 +1448 4 0 445 449 444 196 +1449 4 0 605 564 460 469 +1450 4 0 575 564 605 469 +1451 4 0 541 200 619 574 +1452 4 0 564 436 419 413 +1453 4 0 517 482 63 614 +1454 4 0 154 369 141 123 +1455 4 0 583 498 565 361 +1456 4 0 498 361 637 565 +1457 4 0 622 530 630 575 +1458 4 0 21 30 432 27 +1459 4 0 173 510 160 516 +1460 4 0 311 160 348 516 +1461 4 0 485 140 540 373 +1462 4 0 21 505 580 447 +1463 4 0 490 26 439 571 +1464 4 0 379 544 220 208 +1465 4 0 348 516 181 186 +1466 4 0 186 509 311 516 +1467 4 0 209 202 627 617 +1468 4 0 433 635 529 491 +1469 4 0 430 42 620 44 +1470 4 0 649 430 620 44 +1471 4 0 529 635 541 491 +1472 4 0 404 24 410 21 +1473 4 0 404 410 24 335 +1474 4 0 89 338 359 339 +1475 4 0 450 328 482 517 +1476 4 0 517 328 482 614 +1477 4 0 78 59 537 621 +1478 4 0 588 396 281 356 +1479 4 0 286 488 588 356 +1480 4 0 424 543 593 422 +1481 4 0 463 607 408 16 +1482 4 0 389 381 413 469 +1483 4 0 413 469 575 626 +1484 4 0 626 469 575 545 +1485 4 0 554 11 543 422 +1486 4 0 459 624 646 536 +1487 4 0 332 543 593 424 +1488 4 0 631 554 424 422 +1489 4 0 153 431 629 378 +1490 4 0 545 48 530 626 +1491 4 0 626 530 545 575 +1492 4 0 59 621 78 79 +1493 4 0 160 510 348 516 +1494 4 0 626 590 575 49 +1495 4 0 576 434 112 637 +1496 4 0 498 576 112 637 +1497 4 0 346 651 638 608 +1498 4 0 13 442 412 362 +1499 4 0 13 467 412 442 +1500 4 0 132 142 633 128 +1501 4 0 184 180 172 170 +1502 4 0 631 332 424 554 +1503 4 0 531 573 579 51 +1504 4 0 521 571 563 18 +1505 4 0 599 625 282 340 +1506 4 0 622 630 605 575 +1507 4 0 562 442 362 412 +1508 4 0 193 180 170 141 +1509 4 0 50 644 636 615 +1510 4 0 443 466 20 19 +1511 4 0 616 542 533 491 +1512 4 0 413 594 564 52 +1513 4 0 621 53 600 405 +1514 4 0 362 562 446 27 +1515 4 0 403 547 321 481 +1516 4 0 403 481 321 329 +1517 4 0 562 442 412 10 +1518 4 0 493 459 536 599 +1519 4 0 493 599 536 282 +1520 4 0 450 86 328 517 +1521 4 0 413 602 610 46 +1522 4 0 29 23 28 20 +1523 4 0 223 409 433 491 +1524 4 0 621 59 537 54 +1525 4 0 13 362 412 446 +1526 4 0 439 422 11 14 +1527 4 0 639 473 631 422 +1528 4 0 450 612 584 517 +1529 4 0 450 482 612 517 +1530 4 0 413 641 602 52 +1531 4 0 447 10 24 562 +1532 4 0 531 573 534 579 +1533 4 0 380 345 468 604 +1534 4 0 587 427 444 618 +1535 4 0 613 567 600 534 +1536 4 0 218 386 238 643 +1537 4 0 643 238 423 386 +1538 4 0 347 496 352 604 +1539 4 0 63 345 517 614 +1540 4 0 584 612 63 517 +1541 4 0 629 431 585 418 +1542 4 0 153 431 585 629 +1543 4 0 463 539 478 607 +1544 4 0 463 539 607 16 +1545 4 0 564 609 475 575 +1546 4 0 533 529 402 616 +1547 4 0 376 630 564 518 +1548 4 0 645 54 600 621 +1549 4 0 380 468 472 604 +1550 4 0 604 468 472 352 +1551 4 0 380 468 549 472 +1552 4 0 570 187 373 374 +1553 4 0 606 413 641 640 +1554 4 0 413 610 602 640 +1555 4 0 458 467 13 9 +1556 4 0 467 458 13 371 +1557 4 0 11 422 26 543 +1558 4 0 25 17 425 15 +1559 4 0 646 536 280 493 +1560 4 0 646 624 280 536 +1561 4 0 647 430 44 42 +1562 4 0 618 544 220 379 +1563 4 0 648 6 486 7 +1564 4 0 648 6 538 486 +1565 4 0 403 633 547 481 +1566 4 0 403 328 633 481 +1567 4 0 483 127 628 578 +1568 4 0 486 7 12 14 +1569 4 0 53 56 352 496 +1570 4 0 340 288 284 625 +1571 4 0 283 340 284 625 +1572 4 0 561 352 472 468 +1573 4 0 86 450 328 403 +1574 4 0 329 403 481 328 +1575 4 0 455 288 284 372 +1576 4 0 501 288 284 455 +1577 4 0 376 530 575 630 +1578 4 0 630 376 609 575 +1579 4 0 430 479 42 647 +1580 4 0 621 405 600 534 +1581 4 0 22 28 20 443 +1582 4 0 643 238 229 423 +1583 4 0 481 633 547 142 +1584 4 0 558 428 551 652 +1585 4 0 509 611 331 508 +1586 4 0 513 514 331 611 +1587 4 0 509 513 331 611 +1588 4 0 601 9 1 3 +1589 4 0 289 288 344 501 +1590 4 0 515 32 399 34 +1591 4 0 403 321 349 329 +1592 4 0 392 229 643 238 +1593 4 0 618 445 544 379 +1594 4 0 618 587 544 445 +1595 4 0 531 613 534 573 +1596 4 0 629 153 448 628 +1597 4 0 538 473 597 486 +1598 4 0 597 473 639 486 +1599 4 0 650 31 608 346 +1600 4 0 607 505 580 21 +1601 4 0 288 455 289 372 +1602 4 0 289 455 288 501 +1603 4 0 376 530 590 575 +1604 4 0 49 594 475 575 +1605 4 0 356 279 281 274 +1606 4 0 550 209 444 500 +1607 4 0 362 412 446 562 +1608 4 0 529 433 491 223 +1609 4 0 455 372 284 283 +1610 4 0 465 501 455 289 +1611 4 0 465 289 344 501 +1612 4 0 445 209 444 587 +1613 4 0 153 642 127 628 +1614 4 0 294 385 291 414 +1615 4 0 283 625 459 599 +1616 4 0 613 531 51 573 +1617 4 0 636 573 613 51 +1618 4 0 557 621 568 537 +1619 4 0 558 551 520 5 +1620 4 0 500 209 202 627 +1621 4 0 635 200 541 574 +1622 4 0 595 200 635 574 +1623 4 0 558 652 551 5 +1624 4 0 534 579 573 615 +1625 4 0 605 575 630 564 +1626 4 0 31 346 32 608 +1627 4 0 631 424 639 422 +1628 4 0 383 346 638 26 +1629 4 0 469 575 564 413 +1630 4 0 15 560 332 598 +1631 4 0 15 554 332 560 +1632 4 0 586 557 534 615 +1633 4 0 573 586 534 615 +1634 4 0 332 543 598 593 +1635 4 0 543 332 598 15 +1636 4 0 609 575 564 630 +1637 4 0 554 631 332 453 +1638 4 0 424 554 543 422 +1639 4 0 608 346 651 650 +1640 4 0 487 495 430 479 +1641 4 0 645 621 534 557 +1642 4 0 645 621 600 534 +1643 4 0 542 491 541 574 +1644 4 0 541 635 574 491 +1645 4 0 636 644 586 573 +1646 4 0 573 586 615 644 +1647 4 0 543 634 598 593 +1648 4 0 497 127 642 628 +1649 4 0 598 543 15 634 +1650 4 0 25 15 543 634 +1651 4 0 473 519 597 453 +1652 4 0 595 574 635 491 +1653 4 0 636 51 615 573 +1654 4 0 644 573 636 615 +$EndElements +$ElementData +1 +"color" +1 +0.0 +3 +0 +1 +1654 +1 7.56199 +2 4.86806 +3 4.40144 +4 6.42934 +5 4.22059 +6 5.73014 +7 6.38728 +8 6.65278 +9 6.11566 +10 8.59831 +11 4.59846 +12 3.75402 +13 4.81655 +14 5.303 +15 4.23688 +16 4.44352 +17 9.61146 +18 4.02007 +19 6.55381 +20 4.32183 +21 3.77651 +22 4.28126 +23 4.67035 +24 4.25302 +25 3.24949 +26 3.81682 +27 3.6786 +28 5.26567 +29 5.75883 +30 4.40013 +31 4.8604 +32 3.88159 +33 3.62912 +34 6.09732 +35 6.23606 +36 6.81931 +37 3.98474 +38 5.09313 +39 7.92162 +40 5.91342 +41 5.89822 +42 7.79576 +43 3.26766 +44 6.40478 +45 3.30998 +46 5.75804 +47 4.44341 +48 5.56712 +49 7.92901 +50 7.32341 +51 4.11488 +52 7.27876 +53 4.46523 +54 4.41017 +55 4.24074 +56 5.18865 +57 3.67411 +58 3.93323 +59 6.27803 +60 5.7046 +61 5.43246 +62 6.62422 +63 6.87791 +64 4.8315 +65 4.41484 +66 3.44597 +67 4.80585 +68 4.76576 +69 5.09151 +70 3.90176 +71 3.98978 +72 7.05842 +73 5.79771 +74 5.72113 +75 5.39406 +76 8.36837 +77 6.57885 +78 3.81664 +79 5.04602 +80 5.13045 +81 4.17786 +82 4.12193 +83 5.498 +84 3.9477 +85 4.17729 +86 4.53085 +87 4.87674 +88 5.63865 +89 4.91132 +90 5.42233 +91 7.2101 +92 6.62552 +93 5.99626 +94 5.99827 +95 4.64279 +96 4.40763 +97 7.74874 +98 4.60244 +99 4.55322 +100 3.87632 +101 4.43066 +102 3.5908 +103 4.4961 +104 4.6942 +105 6.85876 +106 6.09827 +107 5.34771 +108 3.88554 +109 4.99917 +110 5.07909 +111 5.16529 +112 6.2445 +113 4.05386 +114 4.0937 +115 4.62717 +116 4.31849 +117 3.26285 +118 3.35407 +119 3.68025 +120 5.5668 +121 4.22251 +122 4.99967 +123 4.02172 +124 7.95474 +125 6.88951 +126 5.11647 +127 3.62751 +128 3.75947 +129 5.71937 +130 4.65378 +131 4.22097 +132 3.54665 +133 4.0164 +134 4.14403 +135 5.88228 +136 3.88365 +137 4.9027 +138 3.88649 +139 3.94684 +140 5.61741 +141 4.86852 +142 4.25794 +143 7.6941 +144 4.73617 +145 3.12373 +146 4.88928 +147 3.62576 +148 4.16485 +149 3.9426 +150 3.46852 +151 6.77747 +152 5.33702 +153 6.56503 +154 5.80932 +155 6.15413 +156 6.85355 +157 4.14906 +158 6.14933 +159 6.69641 +160 3.64734 +161 9.61926 +162 4.84044 +163 6.90865 +164 3.44809 +165 7.79131 +166 4.2801 +167 3.52051 +168 5.45391 +169 3.39718 +170 4.71838 +171 3.97902 +172 6.18658 +173 4.17284 +174 3.92603 +175 6.61929 +176 4.47741 +177 5.4168 +178 4.66072 +179 6.78272 +180 8.92575 +181 3.81346 +182 3.82779 +183 3.59616 +184 4.4729 +185 4.12509 +186 9.13405 +187 4.3469 +188 4.17304 +189 3.37722 +190 4.22285 +191 3.89981 +192 3.56114 +193 5.07249 +194 5.73119 +195 3.31977 +196 7.91262 +197 4.91172 +198 4.3087 +199 4.15402 +200 7.6821 +201 4.41955 +202 4.64581 +203 4.16326 +204 7.51723 +205 6.23256 +206 4.63327 +207 4.85318 +208 6.48807 +209 3.61821 +210 5.09043 +211 8.53276 +212 6.52094 +213 3.90421 +214 4.42601 +215 3.83625 +216 5.54714 +217 3.51603 +218 3.84227 +219 5.7805 +220 5.82631 +221 4.20829 +222 5.28021 +223 4.00498 +224 6.02503 +225 5.06898 +226 5.05237 +227 4.69681 +228 4.59421 +229 4.21961 +230 4.26009 +231 5.25661 +232 6.12045 +233 4.26478 +234 3.42011 +235 3.96254 +236 5.39782 +237 5.34452 +238 5.57074 +239 3.58786 +240 5.48832 +241 5.04805 +242 6.99507 +243 4.86669 +244 8.67723 +245 4.42583 +246 6.08779 +247 8.30081 +248 4.11458 +249 7.33372 +250 4.37632 +251 6.55974 +252 4.06411 +253 7.65217 +254 4.98446 +255 7.00166 +256 9.18261 +257 3.97417 +258 3.76504 +259 4.45173 +260 3.78705 +261 8.85178 +262 5.99438 +263 3.68369 +264 4.64732 +265 5.79147 +266 6.364 +267 5.03453 +268 4.96944 +269 4.75356 +270 3.20622 +271 4.24018 +272 4.41709 +273 4.21315 +274 4.38612 +275 6.51163 +276 5.01322 +277 5.46653 +278 3.97587 +279 6.44458 +280 4.97667 +281 5.55967 +282 5.85158 +283 5.0027 +284 3.48534 +285 6.58618 +286 4.80285 +287 5.94949 +288 4.82903 +289 7.5367 +290 5.70127 +291 7.09932 +292 5.78603 +293 5.97275 +294 3.8847 +295 7.18803 +296 4.24715 +297 6.96264 +298 7.0952 +299 4.63648 +300 6.55609 +301 5.16808 +302 5.24241 +303 3.54707 +304 4.3924 +305 4.0213 +306 4.62658 +307 4.81065 +308 4.56642 +309 6.50736 +310 4.75308 +311 3.8215 +312 3.41325 +313 4.08294 +314 4.91393 +315 5.30757 +316 7.02954 +317 5.24187 +318 4.13738 +319 6.58547 +320 3.70239 +321 3.67817 +322 4.58162 +323 5.24492 +324 4.86733 +325 4.91221 +326 4.2757 +327 5.39939 +328 4.61598 +329 8.42673 +330 6.14168 +331 4.57608 +332 3.81451 +333 4.29124 +334 4.12792 +335 5.02872 +336 5.23399 +337 3.38677 +338 4.50817 +339 5.28311 +340 5.64442 +341 4.71327 +342 6.09192 +343 4.17098 +344 7.35127 +345 5.55052 +346 8.62264 +347 7.92427 +348 4.62414 +349 5.61806 +350 5.34776 +351 6.86714 +352 4.07043 +353 3.76518 +354 3.52133 +355 4.0364 +356 4.23061 +357 5.51497 +358 5.34338 +359 5.2446 +360 3.66377 +361 3.61536 +362 4.93218 +363 5.91732 +364 3.99037 +365 6.86673 +366 4.57754 +367 4.54417 +368 3.49705 +369 3.68222 +370 4.05441 +371 3.28484 +372 3.86728 +373 6.47469 +374 3.8287 +375 4.21948 +376 6.50072 +377 5.2599 +378 5.46621 +379 3.90163 +380 8.20664 +381 5.20216 +382 5.3226 +383 4.03878 +384 8.93219 +385 6.79859 +386 5.0444 +387 4.38992 +388 6.97679 +389 3.69486 +390 3.64051 +391 3.67985 +392 6.23422 +393 3.30838 +394 7.50667 +395 3.94216 +396 6.5134 +397 8.60865 +398 4.39139 +399 3.46463 +400 3.90001 +401 4.26802 +402 3.71403 +403 3.59913 +404 3.15595 +405 4.92885 +406 9.80662 +407 3.63884 +408 3.80748 +409 5.15094 +410 6.35325 +411 4.20196 +412 5.86833 +413 5.91247 +414 3.313 +415 3.37645 +416 4.89339 +417 5.19552 +418 6.53485 +419 7.98558 +420 3.6091 +421 4.05488 +422 4.29978 +423 4.68265 +424 8.03386 +425 5.59842 +426 4.70185 +427 3.61697 +428 5.69205 +429 7.16982 +430 4.13106 +431 3.56492 +432 4.22082 +433 4.55629 +434 4.58142 +435 5.53457 +436 6.93426 +437 4.80377 +438 3.84526 +439 3.94317 +440 3.45505 +441 5.16289 +442 3.25289 +443 3.95152 +444 5.40892 +445 6.95209 +446 4.15315 +447 5.02186 +448 4.01812 +449 3.96462 +450 7.14857 +451 4.97123 +452 4.79327 +453 4.80934 +454 7.58936 +455 4.07601 +456 4.83387 +457 4.20561 +458 4.19693 +459 4.28828 +460 6.64926 +461 6.10328 +462 5.14523 +463 3.29956 +464 7.82612 +465 6.51338 +466 5.14228 +467 6.36966 +468 4.00039 +469 5.25401 +470 4.90217 +471 3.91685 +472 4.04775 +473 3.71452 +474 4.00893 +475 6.15397 +476 4.73995 +477 4.49103 +478 6.01817 +479 4.51129 +480 4.45673 +481 4.53029 +482 4.39765 +483 4.84946 +484 4.41482 +485 5.22789 +486 4.83751 +487 4.52841 +488 4.37907 +489 4.53931 +490 3.94812 +491 5.60107 +492 7.82411 +493 6.10887 +494 3.61105 +495 6.22222 +496 5.87689 +497 4.37764 +498 5.74756 +499 5.41576 +500 3.94004 +501 5.49027 +502 4.62278 +503 5.90077 +504 3.72543 +505 8.58284 +506 9.99379 +507 3.93429 +508 7.00354 +509 3.34162 +510 6.26251 +511 4.5708 +512 4.61934 +513 6.10199 +514 7.60203 +515 3.49142 +516 6.17078 +517 5.25425 +518 6.30042 +519 5.72046 +520 4.47283 +521 4.83221 +522 4.41013 +523 5.97733 +524 3.99931 +525 4.76894 +526 3.74452 +527 6.2368 +528 4.09343 +529 6.26363 +530 6.83661 +531 3.96425 +532 3.43579 +533 5.77657 +534 5.34581 +535 4.68041 +536 4.37814 +537 5.99737 +538 5.3648 +539 5.4205 +540 4.22935 +541 5.82056 +542 3.98684 +543 3.28936 +544 4.1958 +545 4.33791 +546 4.85201 +547 5.22988 +548 6.51603 +549 4.38544 +550 4.03691 +551 4.28065 +552 7.54771 +553 5.3477 +554 3.98013 +555 3.65612 +556 3.6305 +557 4.96827 +558 7.0639 +559 5.12306 +560 5.26116 +561 3.98468 +562 4.06433 +563 4.43174 +564 9.65465 +565 4.48661 +566 7.06711 +567 6.01908 +568 5.78751 +569 6.07332 +570 8.58829 +571 7.11434 +572 3.46196 +573 5.46102 +574 6.3086 +575 5.34819 +576 6.91082 +577 4.47437 +578 7.81942 +579 6.82906 +580 4.72318 +581 4.06215 +582 9.60519 +583 5.3436 +584 4.7691 +585 4.475 +586 5.84693 +587 5.8161 +588 4.01326 +589 8.52049 +590 6.06203 +591 3.94 +592 6.42148 +593 6.28834 +594 4.88767 +595 7.62703 +596 7.56987 +597 5.54109 +598 4.11926 +599 6.37613 +600 4.92981 +601 4.80206 +602 3.26213 +603 6.37042 +604 5.17572 +605 3.76555 +606 5.26092 +607 4.19725 +608 3.19057 +609 5.88572 +610 5.22575 +611 3.782 +612 4.38116 +613 8.53952 +614 4.30787 +615 4.10562 +616 7.62857 +617 5.65392 +618 5.96086 +619 4.91053 +620 6.14863 +621 5.91276 +622 4.27409 +623 5.55369 +624 4.8645 +625 4.77293 +626 3.55957 +627 4.11882 +628 3.68402 +629 6.55336 +630 5.93665 +631 6.29134 +632 5.06148 +633 6.32722 +634 3.56814 +635 4.97852 +636 5.319 +637 7.67988 +638 4.9724 +639 3.58948 +640 3.2273 +641 4.94275 +642 6.132 +643 4.23477 +644 3.8824 +645 6.47761 +646 5.83872 +647 6.52367 +648 9.09261 +649 4.02275 +650 4.5423 +651 3.77518 +652 9.34733 +653 4.29857 +654 3.53165 +655 3.69875 +656 8.91855 +657 8.27777 +658 4.2927 +659 5.44146 +660 4.88306 +661 4.61662 +662 4.66585 +663 4.08773 +664 5.47614 +665 4.82537 +666 5.34588 +667 5.09433 +668 4.74203 +669 4.80349 +670 5.17033 +671 5.55982 +672 5.85245 +673 8.50255 +674 5.05679 +675 8.2833 +676 4.20019 +677 6.65706 +678 5.50201 +679 3.83497 +680 8.04853 +681 3.98407 +682 4.14575 +683 4.40359 +684 3.83137 +685 7.5115 +686 4.55691 +687 5.02113 +688 4.10109 +689 3.2165 +690 6.76792 +691 7.39527 +692 5.09019 +693 4.66208 +694 4.89628 +695 3.82454 +696 7.89338 +697 4.34543 +698 4.53367 +699 4.2245 +700 7.97378 +701 5.36364 +702 5.48083 +703 5.18437 +704 7.54515 +705 8.01303 +706 6.9711 +707 5.10957 +708 4.65648 +709 4.17603 +710 3.95182 +711 4.30453 +712 4.83791 +713 5.75603 +714 6.26297 +715 4.26312 +716 4.92191 +717 6.49723 +718 5.39117 +719 7.63936 +720 3.8902 +721 5.26165 +722 3.56636 +723 5.80111 +724 8.11139 +725 6.99287 +726 6.0905 +727 4.48145 +728 6.29626 +729 6.41609 +730 4.82834 +731 4.30295 +732 5.95249 +733 9.1162 +734 7.17952 +735 4.41636 +736 7.00516 +737 5.38428 +738 4.57018 +739 5.16323 +740 6.21328 +741 3.84546 +742 8.92755 +743 4.95277 +744 5.60229 +745 4.74588 +746 4.39131 +747 3.53583 +748 4.71464 +749 3.85774 +750 4.32924 +751 4.21807 +752 5.56949 +753 3.92575 +754 4.08047 +755 4.19341 +756 5.43269 +757 5.08675 +758 7.55608 +759 4.60229 +760 5.26588 +761 6.53396 +762 6.09301 +763 8.49182 +764 3.65278 +765 3.7977 +766 4.72003 +767 5.07267 +768 5.39706 +769 5.74691 +770 7.17011 +771 4.60288 +772 6.53685 +773 5.03197 +774 4.75913 +775 5.21044 +776 8.20214 +777 5.1994 +778 5.72262 +779 5.56165 +780 5.11548 +781 4.91619 +782 4.4872 +783 5.68936 +784 4.47124 +785 5.13239 +786 3.56721 +787 6.21762 +788 7.03673 +789 4.75488 +790 6.58105 +791 6.02163 +792 4.0573 +793 5.61253 +794 4.57518 +795 6.37637 +796 4.44356 +797 4.71151 +798 7.569 +799 4.14096 +800 5.59666 +801 4.97895 +802 3.58641 +803 3.31542 +804 5.39692 +805 4.83649 +806 3.97031 +807 5.44832 +808 4.02433 +809 3.60805 +810 5.34786 +811 3.58587 +812 6.69862 +813 3.32895 +814 4.09119 +815 4.58371 +816 3.80674 +817 6.44114 +818 6.223 +819 4.0441 +820 4.80123 +821 4.30222 +822 6.44328 +823 5.35506 +824 6.92359 +825 3.89947 +826 6.49231 +827 4.93294 +828 4.30558 +829 6.36489 +830 6.66548 +831 4.33778 +832 4.17984 +833 5.47755 +834 6.30491 +835 4.8866 +836 3.97457 +837 5.46085 +838 9.49042 +839 5.90533 +840 4.86468 +841 6.77968 +842 4.50722 +843 6.47377 +844 6.71684 +845 7.28311 +846 4.96895 +847 4.62845 +848 4.76509 +849 4.94072 +850 6.06047 +851 5.03461 +852 4.02971 +853 6.54434 +854 6.22769 +855 4.93337 +856 3.68803 +857 3.53863 +858 3.91408 +859 5.65137 +860 7.37176 +861 4.59552 +862 6.93334 +863 3.44661 +864 6.33348 +865 5.02479 +866 5.35196 +867 4.49256 +868 4.90908 +869 5.13244 +870 6.53011 +871 6.74559 +872 6.30754 +873 4.22522 +874 5.22566 +875 4.48669 +876 6.19697 +877 5.32891 +878 5.90513 +879 5.26841 +880 4.69307 +881 6.53259 +882 5.37303 +883 4.84613 +884 6.84862 +885 8.57067 +886 4.51242 +887 4.09543 +888 3.96732 +889 3.54212 +890 7.13459 +891 3.96056 +892 3.53356 +893 7.88643 +894 3.71017 +895 4.50089 +896 6.13237 +897 9.12911 +898 5.99732 +899 4.20221 +900 5.07845 +901 7.39265 +902 3.4358 +903 6.92631 +904 6.19262 +905 8.37263 +906 3.90019 +907 5.27365 +908 8.43827 +909 4.30468 +910 7.89174 +911 4.55601 +912 5.99339 +913 3.9157 +914 6.4819 +915 5.12264 +916 4.56214 +917 4.68284 +918 3.62525 +919 5.50492 +920 3.3911 +921 5.44747 +922 5.1212 +923 3.91631 +924 4.09731 +925 3.90953 +926 3.24567 +927 3.84614 +928 3.16043 +929 5.57228 +930 5.27177 +931 4.70165 +932 6.21956 +933 6.82471 +934 4.75076 +935 5.36529 +936 7.32308 +937 5.56332 +938 4.4607 +939 4.55218 +940 4.41271 +941 4.16343 +942 3.60628 +943 5.64808 +944 5.0414 +945 4.07399 +946 8.06578 +947 5.13059 +948 3.32765 +949 6.87378 +950 6.8715 +951 5.34151 +952 7.4087 +953 4.97386 +954 4.34552 +955 4.26796 +956 4.19602 +957 3.42375 +958 5.85754 +959 5.66926 +960 8.16791 +961 5.85989 +962 5.27303 +963 4.04843 +964 3.73455 +965 6.69521 +966 3.19527 +967 5.41381 +968 4.9373 +969 3.34371 +970 5.277 +971 5.14515 +972 4.27359 +973 3.45159 +974 4.18209 +975 3.97173 +976 6.6748 +977 5.48345 +978 5.03449 +979 6.2847 +980 4.28563 +981 4.42304 +982 8.30151 +983 8.10918 +984 5.2181 +985 6.07928 +986 7.4987 +987 3.86094 +988 7.79415 +989 4.1437 +990 4.22013 +991 4.84238 +992 4.18954 +993 4.63546 +994 5.03533 +995 5.68754 +996 3.66053 +997 4.99215 +998 3.9023 +999 6.64228 +1000 3.66927 +1001 7.59005 +1002 7.84943 +1003 6.12621 +1004 4.28124 +1005 5.25678 +1006 4.49358 +1007 3.83982 +1008 4.1934 +1009 4.15133 +1010 5.9278 +1011 6.99563 +1012 5.9841 +1013 8.90109 +1014 7.652 +1015 7.06981 +1016 4.2989 +1017 4.43713 +1018 3.94864 +1019 5.25543 +1020 5.67571 +1021 4.55211 +1022 5.55705 +1023 4.35115 +1024 3.53053 +1025 4.95254 +1026 5.0626 +1027 5.91199 +1028 3.64351 +1029 4.37971 +1030 6.08977 +1031 8.17508 +1032 9.08688 +1033 6.27308 +1034 5.95361 +1035 5.76509 +1036 4.96722 +1037 5.54433 +1038 4.46812 +1039 5.33303 +1040 6.1708 +1041 6.72636 +1042 5.29678 +1043 4.55251 +1044 8.94976 +1045 3.51383 +1046 9.65923 +1047 5.82992 +1048 4.65022 +1049 4.9202 +1050 5.80657 +1051 3.98189 +1052 5.41173 +1053 4.62405 +1054 3.74779 +1055 3.72462 +1056 4.19243 +1057 8.98073 +1058 5.19122 +1059 4.03261 +1060 3.37577 +1061 5.38447 +1062 7.73223 +1063 8.13835 +1064 4.25916 +1065 4.74505 +1066 7.41008 +1067 7.34217 +1068 4.67887 +1069 7.30568 +1070 4.68001 +1071 4.1343 +1072 4.30236 +1073 4.91304 +1074 3.81816 +1075 4.33604 +1076 7.30661 +1077 3.71466 +1078 5.48295 +1079 5.02695 +1080 5.64749 +1081 4.97985 +1082 5.0635 +1083 4.18982 +1084 6.63653 +1085 6.50817 +1086 4.06997 +1087 4.6217 +1088 3.9456 +1089 5.86381 +1090 4.34958 +1091 4.72955 +1092 7.68562 +1093 4.76352 +1094 4.38867 +1095 7.24025 +1096 8.56583 +1097 7.12327 +1098 7.63126 +1099 4.98995 +1100 5.51299 +1101 6.22274 +1102 8.55485 +1103 4.67541 +1104 5.56093 +1105 4.11592 +1106 5.39012 +1107 4.91738 +1108 4.55802 +1109 9.81191 +1110 9.03824 +1111 4.91096 +1112 5.68686 +1113 5.43295 +1114 4.5376 +1115 7.76145 +1116 6.56722 +1117 5.56414 +1118 6.48512 +1119 7.08636 +1120 4.86379 +1121 5.06374 +1122 4.43781 +1123 6.37562 +1124 8.00607 +1125 5.72785 +1126 7.44421 +1127 8.55665 +1128 5.86133 +1129 9.30702 +1130 5.39706 +1131 9.72751 +1132 3.48947 +1133 4.01753 +1134 6.24749 +1135 5.18517 +1136 3.7291 +1137 5.12041 +1138 5.72019 +1139 8.40329 +1140 4.29092 +1141 6.32703 +1142 4.81643 +1143 6.2805 +1144 8.28778 +1145 6.11067 +1146 4.67958 +1147 6.84822 +1148 6.91117 +1149 8.73063 +1150 5.19026 +1151 8.76106 +1152 7.46817 +1153 4.01789 +1154 4.79286 +1155 4.32607 +1156 8.23324 +1157 4.8066 +1158 6.2838 +1159 6.4227 +1160 9.33195 +1161 4.68307 +1162 6.92146 +1163 6.30771 +1164 7.57291 +1165 7.22122 +1166 6.39772 +1167 5.60827 +1168 3.81708 +1169 3.25156 +1170 8.08526 +1171 7.77888 +1172 4.56788 +1173 8.09687 +1174 3.49101 +1175 4.88315 +1176 9.9666 +1177 5.09136 +1178 4.89489 +1179 8.84418 +1180 4.97986 +1181 5.33513 +1182 5.84621 +1183 3.85303 +1184 4.81127 +1185 7.16765 +1186 5.06141 +1187 7.20188 +1188 4.7328 +1189 5.06946 +1190 3.66104 +1191 4.29874 +1192 3.89884 +1193 6.80851 +1194 5.53224 +1195 7.4339 +1196 5.48488 +1197 8.32916 +1198 5.44496 +1199 5.953 +1200 7.10064 +1201 4.28803 +1202 5.27418 +1203 3.79067 +1204 3.44724 +1205 4.17183 +1206 7.19842 +1207 4.32375 +1208 3.51299 +1209 7.615 +1210 5.69386 +1211 6.73423 +1212 4.51568 +1213 6.08616 +1214 5.21758 +1215 8.14411 +1216 4.06477 +1217 5.22976 +1218 5.07475 +1219 5.92439 +1220 4.9689 +1221 5.09276 +1222 7.43835 +1223 6.71407 +1224 7.02283 +1225 6.5295 +1226 4.40292 +1227 5.83422 +1228 3.70634 +1229 3.52758 +1230 6.0864 +1231 4.79487 +1232 5.2648 +1233 6.60461 +1234 4.95882 +1235 9.41937 +1236 5.13095 +1237 5.28013 +1238 5.44854 +1239 7.71878 +1240 5.56885 +1241 8.76006 +1242 4.56393 +1243 5.90289 +1244 6.17245 +1245 5.47762 +1246 6.85481 +1247 3.17205 +1248 4.86204 +1249 4.43452 +1250 6.97671 +1251 5.3337 +1252 5.43708 +1253 5.01141 +1254 7.23168 +1255 3.70348 +1256 4.66871 +1257 8.66635 +1258 7.63642 +1259 6.58896 +1260 5.63525 +1261 5.18847 +1262 4.60493 +1263 8.295 +1264 7.64526 +1265 3.59029 +1266 8.30829 +1267 5.61988 +1268 4.40627 +1269 8.59727 +1270 7.237 +1271 5.90024 +1272 4.03286 +1273 4.8429 +1274 7.10562 +1275 6.50655 +1276 4.64487 +1277 4.69878 +1278 7.97432 +1279 4.02501 +1280 5.38605 +1281 4.92341 +1282 5.07646 +1283 3.75685 +1284 5.31243 +1285 5.7707 +1286 5.68964 +1287 5.96062 +1288 7.85077 +1289 8.21576 +1290 6.68323 +1291 4.30884 +1292 4.784 +1293 5.21908 +1294 4.82005 +1295 4.40245 +1296 4.02024 +1297 3.62885 +1298 3.78701 +1299 3.55008 +1300 4.66264 +1301 5.58137 +1302 4.33701 +1303 4.93396 +1304 3.52374 +1305 7.13144 +1306 5.36387 +1307 8.97625 +1308 5.18498 +1309 9.05048 +1310 8.19838 +1311 4.42885 +1312 8.34232 +1313 3.94079 +1314 4.41342 +1315 7.69708 +1316 4.03687 +1317 4.88914 +1318 4.97387 +1319 5.60074 +1320 3.64249 +1321 3.99359 +1322 5.05358 +1323 7.22987 +1324 9.02307 +1325 3.92924 +1326 5.90228 +1327 6.68582 +1328 9.38571 +1329 4.23719 +1330 3.91918 +1331 6.00412 +1332 8.07751 +1333 4.80956 +1334 5.50254 +1335 9.28165 +1336 4.67539 +1337 4.8626 +1338 6.60907 +1339 6.82969 +1340 5.02785 +1341 4.99683 +1342 7.89183 +1343 9.24249 +1344 5.19206 +1345 4.25973 +1346 5.32035 +1347 4.13126 +1348 5.9532 +1349 6.48769 +1350 3.89076 +1351 5.66956 +1352 7.52047 +1353 5.81182 +1354 7.64656 +1355 5.39628 +1356 5.38481 +1357 4.57187 +1358 7.85941 +1359 3.19563 +1360 4.16723 +1361 7.58062 +1362 5.43379 +1363 4.5491 +1364 9.55822 +1365 5.41463 +1366 3.93709 +1367 5.58151 +1368 7.63004 +1369 7.19653 +1370 6.21067 +1371 4.16437 +1372 7.03794 +1373 6.03681 +1374 7.32543 +1375 8.75148 +1376 9.85852 +1377 5.51133 +1378 8.69481 +1379 5.56414 +1380 6.99819 +1381 3.55529 +1382 5.3928 +1383 4.84586 +1384 7.9864 +1385 6.53059 +1386 4.99042 +1387 4.16435 +1388 6.80177 +1389 5.45811 +1390 5.63078 +1391 3.96717 +1392 3.86136 +1393 3.20475 +1394 8.36851 +1395 5.32051 +1396 4.09927 +1397 4.30378 +1398 6.53894 +1399 9.57378 +1400 6.55006 +1401 6.34936 +1402 4.66909 +1403 4.92672 +1404 6.29711 +1405 6.13071 +1406 7.07983 +1407 3.38745 +1408 6.19644 +1409 3.70599 +1410 8.72514 +1411 5.01474 +1412 6.35499 +1413 8.51238 +1414 6.1006 +1415 8.31744 +1416 8.69373 +1417 5.3837 +1418 3.29415 +1419 3.17415 +1420 4.65337 +1421 3.77393 +1422 3.8875 +1423 7.11242 +1424 4.79596 +1425 4.074 +1426 4.91429 +1427 5.40041 +1428 4.50152 +1429 6.82147 +1430 7.03258 +1431 9.84567 +1432 5.28303 +1433 3.28496 +1434 5.3585 +1435 5.80604 +1436 6.24381 +1437 3.80452 +1438 8.7948 +1439 6.69635 +1440 5.38362 +1441 8.19043 +1442 6.65785 +1443 5.14952 +1444 8.66002 +1445 6.98012 +1446 5.82976 +1447 4.7057 +1448 4.19243 +1449 4.46766 +1450 4.94058 +1451 8.7967 +1452 5.51495 +1453 4.0043 +1454 5.16481 +1455 6.42095 +1456 6.01744 +1457 3.71544 +1458 5.73042 +1459 8.12425 +1460 3.95837 +1461 7.51813 +1462 9.24805 +1463 7.61923 +1464 4.43411 +1465 3.83737 +1466 3.95716 +1467 7.15998 +1468 5.65757 +1469 3.42947 +1470 7.66079 +1471 5.68317 +1472 4.17696 +1473 3.43991 +1474 4.08425 +1475 6.28225 +1476 5.03584 +1477 5.6927 +1478 4.82533 +1479 7.60644 +1480 3.80633 +1481 7.85466 +1482 4.0313 +1483 5.53088 +1484 4.79008 +1485 6.91984 +1486 7.05097 +1487 5.06758 +1488 5.28323 +1489 3.97634 +1490 7.07548 +1491 6.99741 +1492 5.39725 +1493 3.70965 +1494 5.20786 +1495 3.35697 +1496 8.30445 +1497 6.24412 +1498 5.02406 +1499 4.3192 +1500 3.75267 +1501 3.75419 +1502 6.70461 +1503 7.29339 +1504 7.25608 +1505 4.67025 +1506 7.00533 +1507 4.95845 +1508 5.9428 +1509 8.22798 +1510 6.09413 +1511 6.69181 +1512 4.68312 +1513 8.54909 +1514 9.17576 +1515 4.67904 +1516 5.70206 +1517 3.82361 +1518 4.83649 +1519 4.49647 +1520 6.62776 +1521 3.87563 +1522 3.82749 +1523 7.136 +1524 5.46372 +1525 7.49927 +1526 4.77056 +1527 6.99557 +1528 5.41681 +1529 5.67049 +1530 9.09783 +1531 6.2033 +1532 5.7676 +1533 6.10859 +1534 5.64874 +1535 4.25459 +1536 4.24224 +1537 7.54998 +1538 4.6898 +1539 3.65217 +1540 6.77849 +1541 7.38216 +1542 5.01269 +1543 9.63731 +1544 5.93312 +1545 6.67582 +1546 4.31103 +1547 7.11233 +1548 9.36116 +1549 5.26081 +1550 5.69302 +1551 3.48767 +1552 6.63839 +1553 6.58539 +1554 7.28664 +1555 3.81367 +1556 4.57632 +1557 5.76642 +1558 5.47675 +1559 4.10006 +1560 7.47012 +1561 4.71169 +1562 7.33109 +1563 3.61097 +1564 7.2049 +1565 5.17177 +1566 5.69784 +1567 5.66136 +1568 5.26364 +1569 5.80611 +1570 6.17947 +1571 7.04854 +1572 8.77365 +1573 4.85623 +1574 3.77604 +1575 4.3199 +1576 5.59875 +1577 7.20581 +1578 8.22279 +1579 6.75557 +1580 6.15071 +1581 8.40391 +1582 5.84813 +1583 6.71808 +1584 9.4805 +1585 5.78575 +1586 5.53995 +1587 6.22247 +1588 6.41044 +1589 4.20686 +1590 5.13741 +1591 9.43675 +1592 4.7142 +1593 3.98455 +1594 7.70331 +1595 5.7983 +1596 5.38736 +1597 6.27297 +1598 5.693 +1599 7.78512 +1600 9.5604 +1601 3.88507 +1602 5.01882 +1603 7.63484 +1604 5.06804 +1605 4.18197 +1606 4.43359 +1607 4.34535 +1608 4.02395 +1609 7.2371 +1610 8.47037 +1611 4.49746 +1612 8.23039 +1613 4.43065 +1614 4.82179 +1615 7.15842 +1616 4.60424 +1617 4.60142 +1618 4.98153 +1619 4.82699 +1620 6.48302 +1621 5.81494 +1622 9.77863 +1623 9.18164 +1624 8.97711 +1625 6.39388 +1626 4.3432 +1627 8.33951 +1628 5.09327 +1629 5.99447 +1630 4.3455 +1631 6.29698 +1632 3.33295 +1633 6.59657 +1634 6.95084 +1635 3.19532 +1636 5.517 +1637 5.79544 +1638 5.11606 +1639 5.09728 +1640 6.96594 +1641 4.43697 +1642 8.62959 +1643 6.33994 +1644 4.6679 +1645 6.9788 +1646 4.62802 +1647 9.58879 +1648 4.3363 +1649 5.16264 +1650 7.16104 +1651 5.92186 +1652 7.45343 +1653 3.24729 +1654 9.37208 +$EndElementData diff --git a/test/user/testdata/shark_22_ascii_missing_node.msh b/test/user/testdata/shark_22_ascii_missing_node.msh new file mode 100644 index 00000000..e13b4a10 --- /dev/null +++ b/test/user/testdata/shark_22_ascii_missing_node.msh @@ -0,0 +1,3978 @@ +$MeshFormat +2.2 0 8 +$EndMeshFormat +$Nodes +652 +2 -0.0729126 0.0537921 0.00170478 +3 -0.072634 0.0799069 0.0578949 +4 -0.0715817 0.0520377 0.00292576 +5 -0.0701949 0.0802569 0.0450431 +6 -0.0687698 0.060971 0.00326551 +7 -0.06778 0.060358 0.00473741 +8 -0.0672796 0.0809249 0.0425553 +9 -0.0658074 0.0806443 0.0552302 +10 -0.064933 0.0788176 0.0453762 +11 -0.0636555 0.0610198 0.00141989 +12 -0.0636111 0.0566004 -0.000556663 +13 -0.0636791 0.0819076 0.0524468 +14 -0.0623445 0.0580268 0.00335683 +15 -0.0624856 0.0671058 0.00581638 +16 -0.0601398 0.0781111 0.0317589 +17 -0.0599443 0.0685632 0.00992449 +18 -0.0592787 0.0571239 0.00105116 +19 -0.0587906 0.0719999 0.0117948 +20 -0.0575605 0.0730663 0.016213 +21 -0.057624 0.0811803 0.0403639 +22 -0.0572339 0.0769387 0.0223219 +23 -0.0559974 0.0749629 0.0235691 +24 -0.0542321 0.0763209 0.0344665 +25 -0.0540672 0.0649483 0.00821813 +26 -0.0541685 0.0661135 0.00437935 +27 -0.0532966 0.0805356 0.0466758 +28 -0.0517252 0.0761185 0.0183218 +29 -0.0505257 0.068877 0.0152572 +30 -0.0503803 0.0772638 0.0406423 +31 -0.0472855 0.0641041 0.00381053 +32 -0.0469016 0.0648796 0.00821733 +33 -0.0474599 0.0727268 0.0265623 +34 -0.0464733 0.070912 0.0103373 +35 -0.0444756 0.0755674 0.0221683 +36 -0.0440208 0.0774313 0.0371107 +37 -0.0434135 0.0685101 0.0213943 +38 -0.0425401 0.0668787 0.0159114 +39 -0.0405353 0.0730163 0.0309862 +40 -0.0386417 0.073548 0.0160682 +41 -0.037401 0.0664899 0.0122191 +42 -0.0358693 0.0689445 0.0243885 +43 -0.0351058 0.0687771 0.0124837 +44 -0.0333614 0.071165 0.0238503 +45 -0.0325564 0.0696271 0.024504 +46 -0.032455 0.0625178 0.0200737 +47 -0.0305469 0.0729973 0.0173921 +48 -0.0276941 0.0652386 0.0128238 +49 -0.0272717 0.0628782 0.0141328 +50 -0.0263428 0.00735496 0.00505748 +51 -0.0256055 0.00658056 0.00327552 +52 -0.0252856 0.0610141 0.0227762 +53 -0.0250237 -0.00678856 0.00359213 +54 -0.0242889 -0.00589458 0.00589675 +55 -0.0216872 0.0639735 0.0255561 +56 -0.0215721 -0.0119744 0.00619585 +57 -0.0195136 0.0542304 0.0216195 +58 -0.0168343 0.0649534 0.0236547 +59 -0.0161373 -0.00420129 0.00881529 +60 -0.0148726 0.0585475 0.0106707 +61 -0.0140647 0.0517836 0.0159197 +62 -0.0142986 0.0543801 0.0051496 +63 -0.0139611 -0.0178642 0.00651265 +64 -0.0139803 0.0554055 0.0115694 +65 -0.0124373 0.0606817 0.0122622 +66 -0.0127423 0.0580719 0.0285553 +67 -0.0127412 -0.0704232 0.0234664 +68 -0.0126173 -0.0801905 0.022154 +69 -0.0125269 0.0592002 0.0346418 +70 -0.0122498 -0.080596 0.0191154 +71 -0.0121442 -0.0691943 0.0191352 +72 -0.0123618 0.0658492 0.0197519 +73 -0.0121018 -0.063334 0.0245151 +74 -0.0118539 0.0462485 0.0243954 +75 -0.0111067 0.0637388 0.0161162 +76 -0.0110042 -0.0624802 0.0276395 +77 -0.0109072 0.046219 0.0183571 +78 -0.0107037 -0.000325242 0.00950432 +79 -0.010183 -0.0121386 0.00674337 +80 -0.00977442 -0.0638147 0.0162637 +81 -0.0097669 -0.0699334 0.0156591 +82 -0.00942656 -0.0836042 0.0182705 +83 -0.009321 -0.0852334 0.0216727 +84 -0.00803502 0.0401179 0.0263407 +85 -0.00857808 -0.0579335 0.0163943 +86 -0.00793158 -0.0190616 0.0121625 +87 -0.00782675 0.0573514 0.028038 +88 -0.00773028 -0.0620746 0.0302044 +89 -0.00764665 0.0537773 0.00961295 +90 -0.00721562 -0.0507362 0.0224357 +91 -0.00717408 -0.0528249 0.0179333 +92 -0.00651588 -0.00739691 0.013024 +93 -0.00691116 -0.00014073 0.00823716 +94 -0.00661131 0.044183 0.0123 +95 -0.00658663 0.0535365 0.0326225 +96 -0.00630954 -0.0850657 0.0194796 +97 -0.00616497 -0.0797841 0.0261073 +98 -0.00582999 -0.0494502 0.0287705 +99 -0.00563359 0.0476479 0.00934546 +100 -0.00506609 -0.0425596 0.0250833 +101 -0.00453974 -0.0405694 0.0173853 +102 -0.00447266 0.0319291 0.0205877 +103 -0.00434886 0.0267225 0.00648417 +104 -0.00418386 0.0253438 0.00842196 +105 -0.0041733 -0.0606038 0.0122716 +106 -0.00385183 0.0479538 0.00869149 +107 -0.00333705 0.051389 0.031593 +108 -0.00333565 -0.0693881 0.0119551 +109 -0.00333748 -0.0650683 0.0110291 +110 -0.00292457 0.0475597 0.0319288 +111 -0.00280471 -0.0353375 0.0238411 +112 -0.00273019 -0.0493159 0.0135756 +113 -0.00255346 -0.0452657 0.0126112 +114 -0.00249178 -0.0598565 0.010934 +115 -0.00247351 -0.0533955 0.0149632 +116 -0.00280465 0.0288144 0.0300227 +117 -0.00225175 -0.030519 0.0236922 +118 -0.00205777 -0.0595101 0.00715068 +119 -0.0018581 -0.0627033 0.0116048 +120 -0.00150112 -0.0384203 0.0313885 +121 -0.00143547 -0.0337232 0.0176227 +122 -0.00136747 -0.062725 0.0150152 +123 -0.000884775 -0.0587825 0.0143119 +124 -0.000624659 -0.0247814 0.0257906 +125 -0.000489974 0.0225414 0.0188523 +126 -6.05566e-05 0.0171338 0.0234086 +127 0.00150381 0.0360475 0.00675461 +128 0.000282178 -0.0241462 0.0174969 +129 0.000347869 -0.0675237 0.0324883 +130 0.000429839 -0.0422219 0.0349169 +131 0.00028168 -0.0273698 0.0312235 +132 0.000952705 -0.0267391 0.0143612 +133 0.00105244 0.0186951 0.00689988 +134 0.0011109 -0.0779453 0.014663 +135 0.00137887 0.00842564 0.0258445 +136 0.00107238 -0.0462225 0.00980545 +137 0.00158113 -0.0561697 0.005809 +138 0.00165921 -0.0142314 0.0114909 +139 0.00169065 -0.00330978 0.027848 +140 0.0017282 0.0264299 0.00972258 +141 0.00196109 -0.062067 0.0125082 +142 0.00198494 -0.0249792 0.0122768 +143 0.00206797 -0.0322322 0.0125632 +144 0.00219287 -0.00991015 0.0199027 +145 0.00223228 -0.065619 0.00972103 +146 0.00226787 -0.06664 0.0139131 +147 0.00233081 0.00970751 0.0349608 +148 0.0023033 -0.0550711 0.0357611 +149 0.00284591 -0.0695874 0.0109337 +150 0.00313658 0.0123831 0.0152878 +151 0.00325266 -0.000639164 0.0164744 +152 0.00354678 -0.0651674 0.00553443 +153 0.00434877 0.0392681 0.00656793 +154 0.0034004 -0.0624097 0.0143354 +155 0.00410027 0.052311 0.0146156 +156 0.00425687 -0.0110681 0.0377954 +157 0.0043501 -0.0020508 0.015115 +158 0.00444422 -0.0785667 0.0168482 +159 0.00471578 -0.00872746 0.0133588 +160 0.00486541 0.0192794 0.0102326 +161 0.00475235 0.0259901 0.00777948 +162 0.00497525 -0.0797755 0.0244877 +163 0.0052286 0.0545416 0.0234287 +164 0.00513856 -0.0361953 0.00904286 +165 0.00543656 -0.016404 0.0117933 +166 0.00521097 0.0361763 0.0357574 +167 0.00563068 0.0458779 0.0101474 +168 0.00602624 -0.0598053 0.00448538 +169 0.00669265 -0.0730234 0.0300997 +170 0.00671975 -0.0647944 0.0149968 +171 0.00743572 0.0219428 0.00498754 +172 0.00806977 -0.0676622 0.0106835 +173 0.00858002 0.0185363 0.00804532 +174 0.00900922 -0.0527441 0.0382868 +175 0.00967438 -0.0310472 0.0412759 +176 0.00969027 -0.0470756 0.00574739 +177 0.00982547 -0.0777201 0.0238208 +178 0.010337 -0.0646559 0.00738197 +179 0.0103691 -0.0715108 0.0301524 +180 0.0108524 -0.0651923 0.0107074 +181 0.0112352 0.0223598 0.00496048 +182 0.0115762 0.0360388 0.034027 +183 0.011811 0.0150563 0.0411225 +184 0.0119389 -0.0710873 0.0142927 +185 0.011481 0.000850754 0.00890493 +186 0.0122581 0.0177891 0.00726338 +187 0.0126044 0.0285097 0.0071727 +188 0.0126077 -0.0410848 0.00487059 +189 0.01325 0.0245576 0.00385279 +190 0.0133342 -0.0301914 0.00695184 +191 0.0134526 -0.00467313 0.044297 +192 0.0140263 0.0415073 0.0128325 +193 0.0139319 -0.0627506 0.0126489 +194 0.0144402 0.0213321 0.0408733 +195 0.0145153 -0.0120242 0.00709154 +196 0.0145254 0.0314471 0.00762861 +197 0.0143606 -0.0539791 0.00638859 +198 0.0153705 -0.0588177 0.00913193 +199 0.0158483 0.0424843 0.0267153 +200 0.0161677 0.0082135 0.0752128 +201 0.0160709 -0.0693691 0.0267104 +202 0.0163112 0.021127 0.00658374 +203 0.0163956 0.0418119 0.0180916 +204 0.0166653 0.00513625 0.0449469 +205 0.0171438 -0.00939438 0.0462661 +206 0.0174416 -0.0497054 0.0373642 +207 0.0174198 -0.0656937 0.0159871 +208 0.0177387 0.0346114 0.0053358 +209 0.0178439 0.0247259 0.00729322 +210 0.018247 0.0346901 0.00258831 +211 0.0182074 -0.0318958 0.0424624 +212 0.0183988 -0.00142899 0.0496692 +213 0.0188182 -0.018825 0.0447569 +214 0.0188285 0.0147456 0.0461032 +215 0.0188626 0.015416 0.041072 +216 0.0190811 -0.00419709 0.0686858 +217 0.0195945 0.0084326 0.064095 +218 0.0197498 -0.00217441 0.0583864 +219 0.0198208 0.00539755 0.0587622 +220 0.0200137 0.0324539 0.00354185 +221 0.020151 -0.0145671 0.0500049 +222 0.0203386 -0.00326709 0.0702447 +223 0.0209148 0.00523036 0.0681576 +224 0.0208447 0.0121045 0.0546374 +225 0.0209724 0.00970633 0.0633876 +226 0.020604 -0.0121123 0.00591309 +227 0.0212498 -0.0289526 0.00565549 +228 0.0216078 -0.0380775 0.00479088 +229 0.0216875 -0.00997672 0.0619769 +230 0.0220658 0.00705093 0.0456869 +231 0.0223002 -0.0558455 0.0110476 +232 0.0223137 -0.0154618 0.0494217 +233 0.0229336 0.00417573 0.0589573 +234 0.0231427 0.0278288 0.0125965 +235 0.0231751 0.027241 0.0309726 +236 0.0233259 0.0160686 0.00756079 +237 0.0234095 0.0318943 0.0199392 +238 0.0234462 -0.00393483 0.0583985 +239 0.0235915 -0.0597066 0.0170609 +240 0.0240196 -0.0108777 0.0466362 +241 0.024123 -0.00330273 0.0464733 +242 0.0242099 -0.0321428 0.0398591 +243 0.0244244 0.00347947 0.0416421 +244 0.024564 -0.0175604 0.0433407 +245 0.0253979 -0.0453083 0.0344803 +246 0.0256103 0.0267734 0.0284514 +247 0.0259312 -0.0445208 0.00878379 +248 0.025959 -0.0133125 0.00624018 +249 0.0265967 -0.0369666 0.00635268 +250 0.0273245 -0.0066598 0.0412078 +251 0.0277597 -0.0467651 0.0304517 +252 0.0275944 -0.0515878 0.0207552 +253 0.0282687 0.0208205 0.0174814 +254 0.0290859 0.0112094 0.012597 +255 0.0293048 -0.0474855 0.0256026 +256 0.0296506 -0.0466043 0.0156453 +257 0.0304236 0.0134394 0.031696 +258 0.0304518 -0.0291908 0.00746031 +259 0.03126 -0.044124 0.016095 +260 0.0321715 -0.043346 0.0242104 +261 0.0322352 -0.0402733 0.0141242 +262 0.0323149 0.01052 0.0200521 +263 0.0324768 -0.0397188 0.0271188 +264 0.0325431 -0.0291932 0.0340382 +265 0.0332479 -0.0329826 0.0117351 +266 0.0338676 -0.0346121 0.0252676 +267 0.0341522 -0.00293196 0.033596 +268 0.0341882 -0.0361716 0.0179088 +269 0.0344969 -0.0256263 0.0309923 +270 0.0345138 -0.00958586 0.0123416 +271 0.0348872 -0.0128566 0.0339912 +272 0.0349524 -0.0273994 0.0177976 +273 0.0349556 -0.000677158 0.0209767 +274 0.0350004 -0.028049 0.00876142 +275 0.0353194 -0.0100316 0.0154749 +276 0.0354214 -0.0195455 0.0173172 +277 0.0355775 -0.0309821 0.0107592 +278 0.0360305 -0.0150581 0.0232372 +279 0.0363938 -0.0285041 0.0132933 +280 0.0374738 -0.00607371 0.0123945 +281 0.041317 -0.0210454 0.0131228 +282 0.0425886 -0.0120136 0.0129537 +283 0.0475164 -0.00753527 0.00853843 +284 0.0492593 -0.00704914 0.00938067 +285 0.0496752 -0.0170405 0.0106038 +286 0.0498676 -0.0259318 0.00619626 +287 0.052402 -0.022331 0.00866719 +288 0.0516897 -0.011391 0.0103437 +289 0.0559595 -0.0106346 0.00698866 +290 0.0596531 -0.0214295 0.0059579 +291 0.066312 -0.0158462 0.00759335 +292 0.0672852 -0.00331292 0.00667068 +293 0.0687074 -0.0027598 0.00829441 +294 0.0687083 -0.0084515 0.00881385 +295 0.0702857 -0.00694567 0.00665748 +296 0.02471 0.00101921 0.00688758 +297 0.00641783 -0.0341512 0.0233596 +298 0.024018 0.00854392 0.00722419 +299 0.0251696 0.00942127 0.00784613 +300 -0.019815 0.0686939 0.0189821 +301 0.0416697 -0.017118 0.00864259 +302 -0.00440288 -0.0698432 0.0205811 +303 -0.0033606 0.0600219 0.0217676 +304 0.0268544 0.00322876 0.0080825 +305 0.00855449 0.0107052 0.00928038 +306 0.0219179 0.00585482 0.0121236 +307 0.0199208 0.0175811 0.0336776 +308 0.0210521 -0.0362113 0.0256186 +309 0.0339797 -0.00194129 0.0163861 +310 0.03202 0.000337126 0.0126992 +311 0.0119633 0.0163586 0.0147908 +312 0.0248778 0.0056119 0.0321775 +313 0.00892971 -0.0563678 0.0287948 +314 0.0174837 0.027107 0.0210333 +315 -0.0170518 0.00346089 0.00554363 +316 0.0144974 -0.0120686 0.0314959 +317 0.00336155 -0.00103205 0.0364574 +318 0.00707711 -0.0204903 0.0185209 +319 0.010517 -0.00309481 0.0232445 +320 -0.00559352 0.0373259 0.0172753 +321 -0.00523735 -0.0230725 0.0111224 +322 0.0151072 -0.0538804 0.0213778 +323 0.0347571 -0.0188174 0.0105515 +324 0.0278657 -0.0183642 0.0156758 +325 -0.00338013 -0.0543805 0.0329679 +326 -0.0196332 0.0593213 0.0251138 +327 0.0648163 -0.0143432 0.00627944 +328 -0.00336175 -0.0187472 0.00979996 +329 -0.0059938 -0.0214388 0.00941436 +330 0.0204933 0.0262773 0.00994486 +331 0.0153554 0.00838654 0.0105168 +332 -0.064082 0.064994 0.00682263 +333 -0.0406296 0.0703091 0.0249838 +334 -0.0197677 0.0563929 0.0156108 +335 -0.0506931 0.0781816 0.0304629 +336 0.0171972 -0.00100568 0.011485 +337 0.0314619 -0.0225976 0.00774901 +338 -0.00980694 0.0515267 0.0104574 +339 -0.00435185 0.0493969 0.0137744 +340 0.0449063 -0.0117353 0.00859937 +341 0.00159087 -0.0450385 0.027858 +342 -0.00469537 -0.0637251 0.0233918 +343 0.0424219 -0.0285632 0.00857374 +344 0.0603894 -0.00835109 0.00935053 +345 -0.0147113 -0.0156046 0.00918376 +346 -0.0528157 0.0611754 0.00480955 +347 -0.0173765 -0.00887149 0.00520522 +348 0.0108104 0.02268 0.0130558 +349 -0.00899905 -0.0208443 0.00915416 +350 -0.0449914 0.0768094 0.0302276 +351 -0.0408502 0.06658 0.00836849 +352 -0.0199988 -0.0118916 0.004906 +353 0.00337131 0.0455887 0.0238561 +354 0.00477413 -0.0721541 0.0211645 +355 -0.00344193 -0.049333 0.032475 +356 0.0427245 -0.0268877 0.00738607 +357 0.0272704 -0.0238375 0.00669928 +358 -0.00610544 -0.0476638 0.0181008 +359 -0.00760153 0.0503529 0.00747858 +360 0.0131109 -0.0422224 0.0405109 +361 0.00214561 -0.0490294 0.0151357 +362 -0.0598224 0.0805424 0.0511855 +363 -0.0204542 0.0588165 0.013102 +364 0.059357 -0.0190886 0.00813027 +365 -0.00100716 0.0422264 0.0325724 +366 0.0325535 -0.0244764 0.012522 +367 -0.000431427 -0.0574818 0.0137747 +368 0.0114251 0.0275734 0.00440942 +369 0.00337666 -0.0559724 0.0148659 +370 -0.0262911 0.0586227 0.0207785 +371 -0.0699467 0.0813567 0.0499003 +372 0.0494602 -0.0133111 0.00757754 +373 0.00758285 0.0333008 0.0104911 +374 0.00657287 0.032122 0.00603963 +375 0.000332803 -0.0511328 0.0180756 +376 -0.021764 0.0620607 0.0118108 +377 -0.0454672 0.075167 0.035911 +378 0.00139884 0.045926 0.0128133 +379 0.0176314 0.0311493 0.00370344 +380 -0.0159418 -0.0158578 0.00793814 +381 -0.0229387 0.0691641 0.0166572 +382 -0.00133409 -0.0449329 0.0187829 +383 -0.0538019 0.0611146 0.00198764 +384 0.0305208 -0.00256491 0.0101919 +385 0.0623596 -0.00697151 0.00683979 +386 0.0236819 -0.00777996 0.0526871 +387 0.0118138 -0.0144241 0.0430193 +388 0.0137156 -0.00365078 0.00732253 +389 -0.0257884 0.0686739 0.0150694 +390 -0.0530331 0.060812 0.00248197 +391 -0.000421194 -0.0523335 0.00879177 +392 0.0193846 -0.00072024 0.0649221 +393 0.00485856 0.0133946 0.0114741 +394 -0.0053823 -0.0743714 0.0141262 +395 0.016958 0.0166471 0.00740593 +396 0.0429338 -0.0266961 0.0110582 +397 -0.0650475 0.05473 0.00191127 +398 0.00924818 0.0356698 0.00715588 +399 -0.042468 0.0652669 0.00790867 +400 0.00699205 0.0348997 0.00576165 +401 -0.012123 0.00171435 0.00688121 +402 0.017741 0.00126373 0.0717161 +403 -0.00477874 -0.0228765 0.0123522 +404 -0.05496 0.0793832 0.0329037 +405 -0.0253736 -0.000654191 0.00342534 +406 0.0220159 -0.0128389 0.0555838 +407 0.0187915 0.00366305 0.0653901 +408 -0.0635923 0.0794618 0.0351284 +409 0.0187293 0.00901455 0.0689246 +410 -0.0507436 0.0790633 0.0364811 +411 0.00440962 0.0291856 0.00589534 +412 -0.0610541 0.0815764 0.0467801 +413 -0.0264169 0.0641898 0.0180225 +414 0.0590681 -0.0129818 0.00969293 +415 0.0316732 -0.013669 0.00892731 +416 -0.0368828 0.0732351 0.028231 +417 0.0147007 -0.0293577 0.0425282 +418 -0.00226105 0.042112 0.00818422 +419 -0.022404 0.068624 0.0211714 +420 0.018834 0.0296379 0.0101126 +421 0.0545664 -0.023882 0.00596013 +422 -0.0610274 0.0626039 0.00623226 +423 0.0209345 -0.0123916 0.0558755 +424 -0.064258 0.0639612 0.00701622 +425 -0.0530259 0.0709966 0.0104874 +426 -0.000350232 0.0328643 0.00950357 +427 0.0179821 0.0260225 0.00525665 +428 -0.071629 0.0809096 0.0500374 +429 0.0431333 -0.00662611 0.0109755 +430 -0.0367738 0.072104 0.0272887 +431 -0.00147996 0.0424733 0.00778004 +432 -0.0489442 0.0792518 0.0424775 +433 0.0178184 0.00830923 0.0698262 +434 -0.00256208 -0.0518644 0.0119693 +435 -0.0024457 0.0347988 0.0115191 +436 -0.0226391 0.067054 0.0236986 +437 -0.0250562 0.070839 0.0181046 +438 0.0157661 -0.010775 0.0444953 +439 -0.0587069 0.0610686 0.00549325 +440 -0.0561989 0.0607157 0.00436391 +441 0.0028322 0.0311045 0.0076099 +442 -0.061857 0.079748 0.0514834 +443 -0.0580072 0.0744854 0.0170926 +444 0.017366 0.0281829 0.00449304 +445 0.0175246 0.0303053 0.00632184 +446 -0.0583716 0.0812348 0.0494755 +447 -0.0627638 0.0811059 0.0418948 +448 0.00958337 0.0391723 0.00889538 +449 0.0164997 0.0327763 0.00400793 +450 -0.0100537 -0.019407 0.0104569 +451 0.0535082 -0.023589 0.00757618 +452 -0.0184567 0.0672393 0.0165986 +453 -0.0660887 0.0639515 0.00557639 +454 -0.0085005 0.0591911 0.0132991 +455 0.0527123 -0.00658592 0.00801901 +456 0.00664445 0.0147496 0.00979726 +457 -0.0323364 0.0646841 0.013176 +458 -0.0684981 0.0817682 0.0541475 +459 0.0424951 -0.00680449 0.0104665 +460 -0.01583 0.0638299 0.0140017 +461 -0.0408586 0.0747808 0.0276312 +462 -0.0213675 0.00505684 0.00440033 +463 -0.0609542 0.0784149 0.029815 +464 0.0458286 -0.0196104 0.0115924 +465 0.0619857 -0.0044448 0.00717137 +466 -0.0549453 0.0736446 0.0144159 +467 -0.0660739 0.0797747 0.0511232 +468 -0.0150243 -0.0138696 0.00597473 +469 -0.0208919 0.0664273 0.014553 +470 -0.0583912 0.0766731 0.0277458 +471 -0.00499489 -0.0492059 0.0154875 +472 -0.0177596 -0.0149926 0.00640227 +473 -0.0656257 0.0638276 0.00437301 +474 -0.00111824 -0.0505712 0.010634 +475 -0.0234714 0.0595273 0.0150887 +476 -0.0117477 -0.00786715 0.0107629 +477 -0.0329423 0.0662408 0.012525 +478 -0.0588644 0.0778049 0.0265316 +479 -0.038272 0.0710121 0.0277124 +480 0.0147178 0.0228905 0.00513556 +481 -0.00242697 -0.0228032 0.0106496 +482 -0.00998317 -0.0196685 0.00798312 +483 0.00194711 0.0338412 0.00734265 +484 -0.0101071 0.0571173 0.0108272 +485 -0.000192036 0.0305177 0.010316 +486 -0.0662236 0.0609953 0.00234663 +487 -0.0383437 0.071981 0.0290737 +488 0.0464353 -0.0271448 0.00729223 +489 -0.0113654 0.0558876 0.00985606 +490 -0.0600686 0.0581853 0.00037707 +491 0.0184892 0.00651809 0.072001 +492 -0.0272353 0.0661385 0.0125002 +493 0.0386787 -0.00939756 0.0110365 +494 -0.00702298 -0.0554164 0.0301677 +495 -0.0387296 0.0725599 0.0291973 +496 -0.0195884 -0.00971304 0.00731553 +497 0.000980398 0.0340005 0.00831153 +498 -0.00251349 -0.0493306 0.0137872 +499 -0.0208118 0.00468072 0.00662791 +500 0.0145465 0.0247675 0.00685396 +501 0.0539643 -0.00601143 0.00911787 +502 0.0615879 -0.00432066 0.00875869 +503 -0.0649217 0.0800024 0.0383643 +504 0.00460493 0.00849738 0.0127005 +505 -0.0606311 0.0803611 0.0379233 +506 -0.00316884 0.0400824 0.00969248 +507 -0.0308482 0.067467 0.0126012 +508 0.0120049 0.00511369 0.00824306 +509 0.0117314 0.0134932 0.00784586 +510 0.0067401 0.0222359 0.00786688 +511 0.000365941 0.0444987 0.0334101 +512 0.00589042 0.0427357 0.0325284 +513 0.0134556 0.013691 0.0071386 +514 0.0155774 0.00572549 0.00675779 +515 -0.0442054 0.0654197 0.00607699 +516 0.00863004 0.0184766 0.00878081 +517 -0.0111016 -0.0170398 0.0107756 +518 -0.0162643 0.06208 0.0123266 +519 -0.0670643 0.0628756 0.0047451 +520 -0.0673064 0.0791769 0.0489333 +521 -0.0566743 0.0588231 0.00264455 +522 -0.0713841 0.080001 0.0523997 +523 -0.0690781 0.0794039 0.0521145 +524 -0.0589744 0.0702988 0.0123753 +525 -0.0108026 0.05228 0.00636676 +526 -0.0113486 0.0541547 0.00728553 +527 -0.0299136 0.0686241 0.0165753 +528 0.0505332 -0.0225927 0.00635398 +529 0.0180077 0.0031318 0.0704387 +530 -0.0235313 0.0640143 0.012641 +531 -0.0235569 0.00584404 0.00381922 +532 0.0384718 -0.0113423 0.0144484 +533 0.0182407 0.00232532 0.0728388 +534 -0.0235752 0.00407866 0.00373027 +535 -0.011585 0.0522432 0.00647843 +536 0.0400312 -0.00904366 0.0126741 +537 -0.0178591 -0.000359808 0.00797485 +538 -0.067167 0.0625514 0.00392853 +539 -0.0596438 0.0779391 0.0290601 +540 0.0013543 0.0302152 0.00901705 +541 0.0168301 0.00522322 0.0737244 +542 0.0174324 0.00448014 0.0738384 +543 -0.0618546 0.0649931 0.00590465 +544 0.0194429 0.0304209 0.00452872 +545 -0.0236633 0.0648084 0.0124456 +546 -0.00249493 -0.0562542 0.012985 +547 -0.0025263 -0.0246783 0.0125409 +548 -0.0396392 0.0718092 0.02876 +549 -0.0158083 -0.0164708 0.00645267 +550 0.016879 0.0245859 0.0055459 +551 -0.0688499 0.0811361 0.0461884 +552 0.0290982 -0.00647478 0.00827907 +553 -0.041817 0.0761358 0.0343691 +554 -0.0642688 0.0653922 0.00517065 +555 -0.0162175 0.00239503 0.00694561 +556 0.00467524 0.0360758 0.00643588 +557 -0.0222973 0.0035638 0.00646752 +558 -0.0708092 0.0801688 0.0482801 +559 -0.0549524 0.0787083 0.0296023 +560 -0.0631054 0.0672415 0.00811831 +561 -0.0155444 -0.0163359 0.0060847 +562 -0.0574097 0.0788047 0.0473507 +563 -0.0558952 0.0591814 0.001764 +564 -0.0177409 0.0619627 0.0144786 +565 -0.00178349 -0.0487397 0.0125937 +566 -0.0111058 0.0522074 0.00829904 +567 -0.0260139 0.00360897 0.00461987 +568 -0.0204566 0.00423454 0.00564674 +569 0.00612936 0.0370467 0.00680554 +570 0.010446 0.0313554 0.00705031 +571 -0.0569353 0.05965 0.00118235 +572 -0.0506685 0.0625792 0.00279292 +573 -0.0249761 0.00485573 0.00443819 +574 0.0172421 0.00725128 0.0738262 +575 -0.0219613 0.0643004 0.0138184 +576 -0.00260185 -0.0513557 0.0142694 +577 -0.0167422 0.00259292 0.00779623 +578 0.00214524 0.0341103 0.00650831 +579 -0.0236765 0.00572293 0.004305 +580 -0.0616879 0.0784644 0.0353636 +581 -0.0125522 0.0533024 0.00573952 +582 -0.00373263 -0.048886 0.014509 +583 -0.00253347 -0.0472982 0.0131992 +584 -0.0128746 -0.017623 0.00940414 +585 -5.43548e-05 0.0393803 0.00728201 +586 -0.0258702 0.00405717 0.00525282 +587 0.0183599 0.0265636 0.00640112 +588 0.0459896 -0.0257989 0.0100883 +589 -0.0295424 0.0680594 0.0247957 +590 -0.0245383 0.0634107 0.0123732 +591 0.0066096 0.0377811 0.00691952 +592 -0.0450015 0.0646553 0.00575343 +593 -0.0622505 0.0661482 0.00839783 +594 -0.0256248 0.0608105 0.0161665 +595 0.017488 0.00853314 0.0720965 +596 -0.0596734 0.0705097 0.00992485 +597 -0.0665798 0.0628689 0.00493615 +598 -0.0624322 0.0664941 0.0080812 +599 0.0436037 -0.00911409 0.00950451 +600 -0.0258241 0.00183578 0.00455937 +601 -0.0702703 0.0796913 0.0546337 +602 -0.027947 0.0630495 0.0231884 +603 -0.0601839 0.0704633 0.0106076 +604 -0.019796 -0.0130118 0.0069497 +605 -0.0183149 0.0630548 0.012418 +606 -0.0302535 0.0701272 0.02364 +607 -0.0574291 0.0790851 0.0314511 +608 -0.0506885 0.0650762 0.00396145 +609 -0.021101 0.0616869 0.0137094 +610 -0.0331684 0.0670427 0.023997 +611 0.0134393 0.00644533 0.00718965 +612 -0.0111807 -0.0194906 0.00818236 +613 -0.0255718 0.00304117 0.00332801 +614 -0.0126697 -0.015488 0.00653208 +615 -0.0247074 0.00660999 0.00551935 +616 0.0173416 0.0031807 0.0727906 +617 0.0172416 0.0236783 0.00588169 +618 0.0190309 0.0293428 0.00437137 +619 0.016715 0.00646681 0.0747173 +620 -0.0362286 0.072292 0.023504 +621 -0.0193589 -0.00042516 0.00470745 +622 -0.0218861 0.0643631 0.0125137 +623 -0.0102557 0.0512168 0.00711881 +624 0.0404202 -0.00631757 0.0116411 +625 0.0462272 -0.00679819 0.0101561 +626 -0.0259792 0.0656558 0.0150971 +627 0.0162732 0.0229634 0.00624384 +628 0.00353474 0.0364474 0.00843339 +629 4.6368e-06 0.0388726 0.00973083 +630 -0.0216501 0.0633078 0.012475 +631 -0.0653553 0.0635995 0.0060088 +632 -0.0129397 0.0533345 0.00604151 +633 -0.00189413 -0.0244631 0.013557 +634 -0.0610974 0.0673557 0.00916116 +635 0.0169636 0.00823874 0.0726305 +636 -0.0262169 0.00566462 0.00486021 +637 -0.00105663 -0.050339 0.013034 +638 -0.0522352 0.0618469 0.00239028 +639 -0.0658611 0.0623674 0.00600767 +640 -0.0308719 0.0671807 0.0240148 +641 -0.0271033 0.0631674 0.0232081 +642 0.000463176 0.0377435 0.00713404 +643 0.0197653 -0.0105149 0.0573133 +644 -0.0261272 0.00574879 0.00514751 +645 -0.0256133 0.00236555 0.00535812 +646 0.0395658 -0.00664927 0.0115095 +647 -0.0346515 0.0704144 0.0260764 +648 -0.0676857 0.0619198 0.00410476 +649 -0.0352382 0.0722683 0.0261851 +650 -0.0489272 0.0632235 0.00329626 +651 -0.0514659 0.0617489 0.00295197 +652 -0.070483 0.0805389 0.0464472 +$EndNodes +$Elements +1654 +1 4 0 26 15 543 25 +2 4 0 227 308 190 188 +3 4 0 203 353 199 163 +4 4 0 331 305 504 150 +5 4 0 142 328 128 138 +6 4 0 490 439 18 571 +7 4 0 364 289 287 414 +8 4 0 296 336 304 298 +9 4 0 564 419 300 381 +10 4 0 398 569 373 591 +11 4 0 486 473 639 422 +12 4 0 338 89 566 489 +13 4 0 332 554 543 424 +14 4 0 80 67 71 302 +15 4 0 149 146 109 108 +16 4 0 98 90 375 342 +17 4 0 341 308 325 313 +18 4 0 147 314 126 116 +19 4 0 124 318 156 131 +20 4 0 245 322 206 308 +21 4 0 348 311 516 186 +22 4 0 135 150 319 151 +23 4 0 147 314 307 311 +24 4 0 464 588 301 528 +25 4 0 461 33 35 333 +26 4 0 196 192 373 314 +27 4 0 108 81 302 122 +28 4 0 366 258 227 357 +29 4 0 511 107 512 353 +30 4 0 146 170 354 172 +31 4 0 297 175 156 130 +32 4 0 130 297 175 308 +33 4 0 318 159 319 195 +34 4 0 154 123 122 342 +35 4 0 261 308 259 260 +36 4 0 132 142 128 318 +37 4 0 241 250 240 205 +38 4 0 226 227 248 324 +39 4 0 575 609 475 49 +40 4 0 375 91 123 90 +41 4 0 260 308 255 251 +42 4 0 517 612 63 482 +43 4 0 120 117 131 297 +44 4 0 318 131 297 156 +45 4 0 147 319 311 307 +46 4 0 131 120 297 130 +47 4 0 120 297 111 117 +48 4 0 308 174 206 360 +49 4 0 148 313 325 175 +50 4 0 148 313 175 174 +51 4 0 302 80 122 81 +52 4 0 107 353 511 110 +53 4 0 322 231 198 197 +54 4 0 61 58 564 57 +55 4 0 240 386 212 221 +56 4 0 121 297 143 117 +57 4 0 121 297 117 111 +58 4 0 307 235 314 182 +59 4 0 307 314 166 182 +60 4 0 417 308 175 316 +61 4 0 308 175 360 417 +62 4 0 601 9 458 1 +63 4 0 459 429 536 599 +64 4 0 211 242 206 308 +65 4 0 528 588 301 356 +66 4 0 316 297 308 175 +67 4 0 197 188 308 228 +68 4 0 231 308 228 197 +69 4 0 231 197 322 308 +70 4 0 188 197 308 361 +71 4 0 322 361 308 197 +72 4 0 259 308 256 255 +73 4 0 298 306 304 299 +74 4 0 302 342 146 122 +75 4 0 251 322 245 308 +76 4 0 298 306 299 236 +77 4 0 342 302 169 129 +78 4 0 157 319 331 150 +79 4 0 190 195 324 227 +80 4 0 146 342 354 154 +81 4 0 190 297 308 324 +82 4 0 236 254 306 299 +83 4 0 354 179 201 322 +84 4 0 308 297 188 361 +85 4 0 361 188 164 297 +86 4 0 195 165 190 318 +87 4 0 307 215 257 235 +88 4 0 194 235 215 307 +89 4 0 174 129 148 313 +90 4 0 169 313 129 174 +91 4 0 322 255 251 201 +92 4 0 366 265 308 258 +93 4 0 227 308 258 366 +94 4 0 258 308 249 265 +95 4 0 227 308 228 258 +96 4 0 448 192 373 196 +97 4 0 228 308 249 258 +98 4 0 296 298 514 336 +99 4 0 125 150 348 126 +100 4 0 125 160 348 150 +101 4 0 244 264 242 316 +102 4 0 264 316 244 271 +103 4 0 224 233 225 219 +104 4 0 107 353 163 199 +105 4 0 217 223 219 225 +106 4 0 308 174 313 206 +107 4 0 206 313 179 174 +108 4 0 241 230 212 233 +109 4 0 241 233 212 218 +110 4 0 267 278 312 273 +111 4 0 267 312 262 273 +112 4 0 206 179 322 245 +113 4 0 242 245 206 308 +114 4 0 144 319 159 157 +115 4 0 265 308 266 272 +116 4 0 218 219 392 233 +117 4 0 264 324 316 271 +118 4 0 324 308 264 316 +119 4 0 297 318 117 131 +120 4 0 128 117 318 124 +121 4 0 354 207 201 177 +122 4 0 207 177 354 184 +123 4 0 155 163 353 203 +124 4 0 131 297 156 130 +125 4 0 395 330 236 202 +126 4 0 164 142 318 190 +127 4 0 253 314 234 311 +128 4 0 307 314 147 166 +129 4 0 331 234 253 254 +130 4 0 306 236 298 331 +131 4 0 156 297 316 175 +132 4 0 324 319 318 316 +133 4 0 297 324 316 308 +134 4 0 373 314 102 125 +135 4 0 167 155 378 192 +136 4 0 278 324 272 269 +137 4 0 278 276 272 324 +138 4 0 319 159 157 336 +139 4 0 267 257 312 243 +140 4 0 307 215 243 257 +141 4 0 156 297 318 316 +142 4 0 207 354 170 184 +143 4 0 124 144 139 156 +144 4 0 267 312 250 243 +145 4 0 144 151 139 319 +146 4 0 318 316 319 144 +147 4 0 316 139 319 144 +148 4 0 139 144 316 156 +149 4 0 316 191 312 319 +150 4 0 316 191 317 156 +151 4 0 313 308 175 174 +152 4 0 253 234 331 311 +153 4 0 331 395 234 236 +154 4 0 272 265 308 366 +155 4 0 103 140 133 510 +156 4 0 235 199 246 314 +157 4 0 246 237 314 199 +158 4 0 144 151 319 157 +159 4 0 92 157 151 144 +160 4 0 92 159 157 144 +161 4 0 395 234 236 330 +162 4 0 395 330 202 348 +163 4 0 348 330 202 209 +164 4 0 324 312 316 271 +165 4 0 266 308 324 272 +166 4 0 324 366 308 227 +167 4 0 242 264 245 308 +168 4 0 272 266 269 324 +169 4 0 135 151 319 139 +170 4 0 40 35 28 29 +171 4 0 88 148 129 342 +172 4 0 325 342 148 88 +173 4 0 314 116 147 166 +174 4 0 77 353 320 94 +175 4 0 331 262 319 306 +176 4 0 319 317 139 316 +177 4 0 450 329 482 328 +178 4 0 183 307 147 166 +179 4 0 188 361 176 197 +180 4 0 169 179 313 174 +181 4 0 314 196 348 373 +182 4 0 102 84 116 353 +183 4 0 102 77 84 353 +184 4 0 191 147 319 317 +185 4 0 307 262 257 312 +186 4 0 307 257 246 235 +187 4 0 307 257 262 246 +188 4 0 128 318 144 124 +189 4 0 246 314 237 253 +190 4 0 314 203 237 234 +191 4 0 142 128 318 138 +192 4 0 253 237 234 314 +193 4 0 306 319 331 336 +194 4 0 307 314 235 246 +195 4 0 316 250 312 191 +196 4 0 450 403 349 329 +197 4 0 121 297 101 143 +198 4 0 382 164 101 297 +199 4 0 369 198 322 193 +200 4 0 264 266 324 269 +201 4 0 322 354 170 207 +202 4 0 322 170 193 207 +203 4 0 353 84 116 110 +204 4 0 70 302 68 83 +205 4 0 331 311 234 395 +206 4 0 323 493 282 301 +207 4 0 269 278 324 271 +208 4 0 278 312 324 271 +209 4 0 207 170 180 184 +210 4 0 207 170 193 180 +211 4 0 325 130 175 308 +212 4 0 146 354 170 154 +213 4 0 354 302 342 146 +214 4 0 161 348 510 181 +215 4 0 182 314 199 235 +216 4 0 322 354 369 170 +217 4 0 231 207 322 198 +218 4 0 313 322 375 341 +219 4 0 375 361 341 322 +220 4 0 322 207 193 198 +221 4 0 297 143 164 101 +222 4 0 221 213 240 232 +223 4 0 190 188 308 297 +224 4 0 341 361 375 382 +225 4 0 341 308 313 322 +226 4 0 134 158 184 354 +227 4 0 247 308 261 249 +228 4 0 263 308 260 251 +229 4 0 318 319 159 144 +230 4 0 309 262 306 319 +231 4 0 250 204 243 312 +232 4 0 448 192 167 378 +233 4 0 37 333 620 35 +234 4 0 37 33 333 35 +235 4 0 297 318 316 324 +236 4 0 167 448 378 153 +237 4 0 212 218 233 219 +238 4 0 88 325 342 494 +239 4 0 246 307 314 253 +240 4 0 307 253 246 262 +241 4 0 126 311 150 348 +242 4 0 388 611 336 514 +243 4 0 348 234 420 314 +244 4 0 236 254 331 306 +245 4 0 348 314 311 234 +246 4 0 211 308 360 417 +247 4 0 373 102 320 125 +248 4 0 316 250 191 438 +249 4 0 250 205 191 438 +250 4 0 254 262 306 309 +251 4 0 254 309 306 310 +252 4 0 299 254 306 310 +253 4 0 331 262 306 254 +254 4 0 292 294 295 293 +255 4 0 194 307 215 204 +256 4 0 304 306 384 299 +257 4 0 267 312 257 262 +258 4 0 353 192 378 155 +259 4 0 319 159 336 195 +260 4 0 353 192 373 378 +261 4 0 336 185 388 195 +262 4 0 312 250 271 267 +263 4 0 271 250 312 316 +264 4 0 261 249 308 265 +265 4 0 268 308 265 261 +266 4 0 247 308 249 228 +267 4 0 227 195 324 226 +268 4 0 366 324 415 337 +269 4 0 337 366 324 357 +270 4 0 190 195 318 324 +271 4 0 156 318 124 144 +272 4 0 263 266 308 264 +273 4 0 251 263 308 264 +274 4 0 197 198 322 369 +275 4 0 154 354 369 342 +276 4 0 188 308 228 227 +277 4 0 79 328 138 92 +278 4 0 316 317 139 156 +279 4 0 360 175 308 174 +280 4 0 255 251 308 322 +281 4 0 255 256 252 308 +282 4 0 247 228 231 308 +283 4 0 247 308 231 256 +284 4 0 134 149 394 354 +285 4 0 83 162 96 302 +286 4 0 161 373 140 348 +287 4 0 88 67 302 68 +288 4 0 302 97 88 68 +289 4 0 512 166 314 182 +290 4 0 420 192 314 234 +291 4 0 348 330 420 234 +292 4 0 192 314 234 203 +293 4 0 91 123 105 115 +294 4 0 394 70 302 81 +295 4 0 309 273 262 319 +296 4 0 319 262 312 273 +297 4 0 67 302 68 70 +298 4 0 271 278 312 267 +299 4 0 66 57 326 58 +300 4 0 188 136 176 361 +301 4 0 157 331 185 504 +302 4 0 136 361 188 164 +303 4 0 244 250 271 316 +304 4 0 71 302 67 70 +305 4 0 244 213 232 240 +306 4 0 81 302 71 70 +307 4 0 354 149 108 146 +308 4 0 314 237 203 199 +309 4 0 506 378 435 629 +310 4 0 244 438 316 213 +311 4 0 97 302 169 162 +312 4 0 244 316 438 250 +313 4 0 313 129 342 169 +314 4 0 382 113 101 164 +315 4 0 506 435 378 94 +316 4 0 91 123 85 105 +317 4 0 308 264 245 251 +318 4 0 242 264 308 316 +319 4 0 450 349 482 329 +320 4 0 314 373 348 125 +321 4 0 92 138 159 144 +322 4 0 395 311 234 348 +323 4 0 278 273 324 312 +324 4 0 373 378 435 320 +325 4 0 147 311 319 135 +326 4 0 126 311 135 150 +327 4 0 126 135 311 147 +328 4 0 314 348 311 126 +329 4 0 83 302 82 70 +330 4 0 378 435 629 373 +331 4 0 195 159 165 318 +332 4 0 316 312 324 319 +333 4 0 156 175 316 387 +334 4 0 336 298 514 331 +335 4 0 88 342 129 302 +336 4 0 319 307 331 311 +337 4 0 253 314 311 307 +338 4 0 311 331 253 307 +339 4 0 297 341 308 130 +340 4 0 314 348 126 125 +341 4 0 147 314 311 126 +342 4 0 61 339 99 338 +343 4 0 250 204 312 191 +344 4 0 305 185 508 331 +345 4 0 211 242 308 316 +346 4 0 211 308 417 316 +347 4 0 213 316 211 417 +348 4 0 214 215 230 204 +349 4 0 244 316 242 211 +350 4 0 244 211 213 316 +351 4 0 465 501 344 502 +352 4 0 108 354 302 394 +353 4 0 313 129 148 342 +354 4 0 337 324 415 248 +355 4 0 337 258 366 357 +356 4 0 121 101 297 111 +357 4 0 382 101 111 297 +358 4 0 157 159 185 336 +359 4 0 226 336 195 324 +360 4 0 307 262 331 253 +361 4 0 307 262 319 331 +362 4 0 331 254 253 262 +363 4 0 248 336 552 296 +364 4 0 319 324 195 336 +365 4 0 248 296 226 336 +366 4 0 324 248 336 552 +367 4 0 147 183 191 307 +368 4 0 282 281 276 323 +369 4 0 281 323 282 301 +370 4 0 109 119 105 122 +371 4 0 297 143 117 318 +372 4 0 109 122 105 80 +373 4 0 308 366 324 272 +374 4 0 297 318 324 190 +375 4 0 297 190 164 318 +376 4 0 214 204 230 212 +377 4 0 224 212 214 230 +378 4 0 297 143 318 164 +379 4 0 264 308 324 266 +380 4 0 264 269 324 271 +381 4 0 132 117 143 318 +382 4 0 130 297 341 120 +383 4 0 341 130 120 98 +384 4 0 277 343 356 279 +385 4 0 325 308 175 313 +386 4 0 109 81 108 122 +387 4 0 109 122 108 146 +388 4 0 348 234 395 330 +389 4 0 341 111 120 297 +390 4 0 341 100 98 120 +391 4 0 341 111 100 120 +392 4 0 226 336 324 248 +393 4 0 318 319 324 195 +394 4 0 275 270 324 309 +395 4 0 309 336 324 319 +396 4 0 552 270 336 324 +397 4 0 273 309 275 324 +398 4 0 403 328 329 450 +399 4 0 382 111 341 297 +400 4 0 361 322 308 341 +401 4 0 361 341 308 297 +402 4 0 342 85 73 90 +403 4 0 342 73 85 80 +404 4 0 323 324 366 276 +405 4 0 361 297 164 382 +406 4 0 96 82 83 302 +407 4 0 45 647 44 42 +408 4 0 179 354 201 177 +409 4 0 53 621 54 347 +410 4 0 117 124 131 318 +411 4 0 156 144 316 318 +412 4 0 369 198 193 141 +413 4 0 342 302 88 67 +414 4 0 67 80 342 302 +415 4 0 73 80 342 67 +416 4 0 342 73 67 76 +417 4 0 372 528 289 285 +418 4 0 285 528 289 287 +419 4 0 355 98 325 494 +420 4 0 122 119 105 123 +421 4 0 394 82 134 302 +422 4 0 494 88 76 342 +423 4 0 109 81 122 80 +424 4 0 447 580 503 505 +425 4 0 114 118 141 145 +426 4 0 311 150 319 135 +427 4 0 108 122 302 146 +428 4 0 204 307 183 194 +429 4 0 191 204 307 183 +430 4 0 382 101 100 111 +431 4 0 382 111 100 341 +432 4 0 318 159 138 144 +433 4 0 588 281 301 356 +434 4 0 87 61 77 57 +435 4 0 318 159 165 138 +436 4 0 7 12 2 486 +437 4 0 316 191 319 317 +438 4 0 208 196 449 445 +439 4 0 322 369 354 313 +440 4 0 354 158 177 162 +441 4 0 354 169 162 179 +442 4 0 313 369 354 342 +443 4 0 179 162 354 177 +444 4 0 130 98 341 355 +445 4 0 325 130 341 355 +446 4 0 337 357 324 248 +447 4 0 324 357 227 248 +448 4 0 588 281 464 301 +449 4 0 375 341 382 98 +450 4 0 454 75 61 155 +451 4 0 353 77 84 74 +452 4 0 331 305 185 504 +453 4 0 311 331 319 150 +454 4 0 378 339 167 106 +455 4 0 318 190 142 165 +456 4 0 138 142 165 318 +457 4 0 18 12 397 14 +458 4 0 298 514 331 513 +459 4 0 118 137 141 168 +460 4 0 298 331 236 395 +461 4 0 395 298 331 513 +462 4 0 93 157 92 159 +463 4 0 354 158 184 177 +464 4 0 151 157 92 93 +465 4 0 78 93 151 92 +466 4 0 378 448 629 153 +467 4 0 102 314 126 125 +468 4 0 126 116 314 102 +469 4 0 61 72 303 75 +470 4 0 39 461 350 553 +471 4 0 350 39 33 461 +472 4 0 311 331 513 395 +473 4 0 311 331 305 509 +474 4 0 353 102 314 116 +475 4 0 204 215 243 307 +476 4 0 106 153 167 378 +477 4 0 97 162 83 302 +478 4 0 107 353 199 512 +479 4 0 297 188 164 190 +480 4 0 147 319 139 135 +481 4 0 77 353 87 74 +482 4 0 353 203 199 314 +483 4 0 512 314 353 199 +484 4 0 37 38 29 35 +485 4 0 485 140 373 125 +486 4 0 398 448 373 196 +487 4 0 196 570 373 398 +488 4 0 324 248 552 415 +489 4 0 415 270 552 324 +490 4 0 52 57 594 564 +491 4 0 285 289 414 287 +492 4 0 438 250 205 240 +493 4 0 524 425 25 17 +494 4 0 29 25 524 425 +495 4 0 87 77 61 353 +496 4 0 93 92 138 159 +497 4 0 93 92 79 138 +498 4 0 203 192 353 155 +499 4 0 192 353 314 203 +500 4 0 88 302 129 97 +501 4 0 169 342 354 302 +502 4 0 147 319 317 139 +503 4 0 435 426 629 373 +504 4 0 197 168 369 176 +505 4 0 369 176 361 197 +506 4 0 157 151 319 150 +507 4 0 307 319 312 191 +508 4 0 312 307 191 204 +509 4 0 628 373 441 374 +510 4 0 513 331 311 509 +511 4 0 49 594 413 46 +512 4 0 303 163 87 61 +513 4 0 146 342 154 122 +514 4 0 274 366 415 337 +515 4 0 274 258 366 337 +516 4 0 87 57 74 66 +517 4 0 304 306 336 384 +518 4 0 204 250 205 191 +519 4 0 110 74 66 87 +520 4 0 163 87 61 353 +521 4 0 204 205 250 241 +522 4 0 387 438 213 316 +523 4 0 150 160 348 311 +524 4 0 313 369 342 375 +525 4 0 313 322 369 375 +526 4 0 97 129 169 302 +527 4 0 504 305 393 150 +528 4 0 181 348 500 187 +529 4 0 610 527 42 44 +530 4 0 44 527 42 620 +531 4 0 311 305 456 509 +532 4 0 311 509 456 516 +533 4 0 365 512 166 116 +534 4 0 116 512 166 314 +535 4 0 509 305 508 331 +536 4 0 322 369 193 170 +537 4 0 535 526 581 632 +538 4 0 182 314 512 199 +539 4 0 497 441 373 540 +540 4 0 37 42 46 527 +541 4 0 500 209 187 348 +542 4 0 312 257 307 243 +543 4 0 323 366 281 276 +544 4 0 348 420 209 196 +545 4 0 366 279 276 272 +546 4 0 202 500 186 348 +547 4 0 386 406 221 232 +548 4 0 64 526 62 489 +549 4 0 336 159 185 195 +550 4 0 404 24 559 335 +551 4 0 404 24 607 559 +552 4 0 384 336 552 270 +553 4 0 244 240 438 213 +554 4 0 244 438 240 250 +555 4 0 430 461 620 333 +556 4 0 461 333 35 620 +557 4 0 61 564 64 334 +558 4 0 381 437 47 413 +559 4 0 279 277 265 258 +560 4 0 279 277 258 274 +561 4 0 186 500 181 348 +562 4 0 140 510 348 160 +563 4 0 377 410 36 350 +564 4 0 202 330 236 209 +565 4 0 380 345 614 468 +566 4 0 99 339 378 106 +567 4 0 378 106 418 99 +568 4 0 378 448 373 629 +569 4 0 194 235 307 182 +570 4 0 194 307 166 182 +571 4 0 194 307 183 166 +572 4 0 353 373 320 378 +573 4 0 68 97 83 302 +574 4 0 347 496 604 476 +575 4 0 161 181 411 373 +576 4 0 570 374 400 368 +577 4 0 40 38 35 29 +578 4 0 364 289 327 528 +579 4 0 324 309 319 273 +580 4 0 353 378 320 94 +581 4 0 358 91 471 375 +582 4 0 134 394 302 354 +583 4 0 394 149 108 354 +584 4 0 172 354 146 149 +585 4 0 382 358 471 375 +586 4 0 101 382 90 358 +587 4 0 651 346 638 390 +588 4 0 382 90 100 101 +589 4 0 334 594 564 475 +590 4 0 369 361 375 322 +591 4 0 322 197 369 361 +592 4 0 342 325 98 494 +593 4 0 325 313 148 342 +594 4 0 342 325 375 98 +595 4 0 115 369 123 367 +596 4 0 342 98 76 494 +597 4 0 369 375 576 115 +598 4 0 353 512 116 314 +599 4 0 336 304 552 296 +600 4 0 336 306 304 298 +601 4 0 226 514 336 296 +602 4 0 108 302 81 394 +603 4 0 181 411 373 374 +604 4 0 26 440 571 383 +605 4 0 26 383 346 440 +606 4 0 211 360 308 206 +607 4 0 87 74 57 77 +608 4 0 358 113 101 382 +609 4 0 195 388 336 226 +610 4 0 241 233 218 238 +611 4 0 155 339 378 353 +612 4 0 345 79 468 476 +613 4 0 213 316 417 175 +614 4 0 387 316 213 175 +615 4 0 312 307 262 319 +616 4 0 435 485 426 373 +617 4 0 435 373 125 485 +618 4 0 299 310 306 384 +619 4 0 26 425 25 34 +620 4 0 118 114 367 434 +621 4 0 26 34 25 608 +622 4 0 223 222 529 392 +623 4 0 527 38 37 35 +624 4 0 37 527 46 38 +625 4 0 342 123 90 375 +626 4 0 342 123 85 90 +627 4 0 335 350 33 35 +628 4 0 350 461 33 35 +629 4 0 85 91 90 123 +630 4 0 259 247 308 261 +631 4 0 629 628 448 373 +632 4 0 633 142 328 128 +633 4 0 629 497 628 373 +634 4 0 303 61 87 72 +635 4 0 236 254 234 331 +636 4 0 341 98 325 355 +637 4 0 373 570 400 569 +638 4 0 398 570 373 569 +639 4 0 49 413 527 46 +640 4 0 49 46 527 457 +641 4 0 49 626 48 527 +642 4 0 241 204 243 250 +643 4 0 49 527 48 457 +644 4 0 392 218 233 238 +645 4 0 233 392 238 223 +646 4 0 178 198 197 141 +647 4 0 198 197 141 369 +648 4 0 364 290 287 528 +649 4 0 419 381 564 413 +650 4 0 92 78 79 59 +651 4 0 192 373 314 353 +652 4 0 386 406 238 423 +653 4 0 367 369 137 391 +654 4 0 437 413 419 606 +655 4 0 413 437 47 606 +656 4 0 239 252 322 255 +657 4 0 454 61 339 155 +658 4 0 34 466 425 29 +659 4 0 221 386 232 240 +660 4 0 60 64 489 484 +661 4 0 484 65 60 64 +662 4 0 212 386 218 221 +663 4 0 241 240 386 212 +664 4 0 241 205 240 212 +665 4 0 607 24 16 470 +666 4 0 620 42 37 527 +667 4 0 37 333 42 620 +668 4 0 95 87 66 69 +669 4 0 113 164 382 361 +670 4 0 410 30 432 21 +671 4 0 371 1 522 458 +672 4 0 527 47 43 40 +673 4 0 596 425 17 15 +674 4 0 393 456 160 311 +675 4 0 110 95 87 66 +676 4 0 160 311 456 516 +677 4 0 512 511 365 166 +678 4 0 353 511 365 512 +679 4 0 128 144 318 138 +680 4 0 341 130 325 308 +681 4 0 87 61 57 58 +682 4 0 419 58 564 72 +683 4 0 414 289 327 364 +684 4 0 320 378 435 94 +685 4 0 364 528 287 289 +686 4 0 212 221 205 240 +687 4 0 134 172 149 354 +688 4 0 134 172 354 184 +689 4 0 319 147 191 307 +690 4 0 589 641 606 436 +691 4 0 347 79 59 476 +692 4 0 345 79 476 92 +693 4 0 92 138 144 328 +694 4 0 86 92 144 328 +695 4 0 32 399 34 38 +696 4 0 306 309 336 310 +697 4 0 347 604 468 476 +698 4 0 347 468 79 476 +699 4 0 614 345 79 468 +700 4 0 384 310 336 270 +701 4 0 439 25 26 422 +702 4 0 196 192 314 420 +703 4 0 348 420 196 314 +704 4 0 132 143 142 318 +705 4 0 164 142 143 318 +706 4 0 386 406 423 221 +707 4 0 35 527 38 40 +708 4 0 158 354 96 162 +709 4 0 169 302 354 162 +710 4 0 334 475 564 363 +711 4 0 155 61 303 75 +712 4 0 94 353 378 339 +713 4 0 224 233 219 212 +714 4 0 214 215 204 194 +715 4 0 204 243 230 241 +716 4 0 204 230 212 241 +717 4 0 391 474 369 136 +718 4 0 286 588 528 356 +719 4 0 35 620 527 47 +720 4 0 136 474 361 565 +721 4 0 566 526 632 64 +722 4 0 490 439 11 14 +723 4 0 209 330 420 348 +724 4 0 35 527 40 47 +725 4 0 76 342 73 98 +726 4 0 77 353 102 320 +727 4 0 268 308 261 260 +728 4 0 167 155 339 378 +729 4 0 465 289 385 344 +730 4 0 255 308 260 259 +731 4 0 335 24 470 33 +732 4 0 559 24 470 335 +733 4 0 522 1 371 428 +734 4 0 347 53 496 54 +735 4 0 559 24 607 470 +736 4 0 476 347 496 54 +737 4 0 312 204 243 307 +738 4 0 230 215 243 204 +739 4 0 241 218 212 386 +740 4 0 241 238 218 386 +741 4 0 29 33 28 23 +742 4 0 23 335 559 470 +743 4 0 297 382 361 341 +744 4 0 336 611 185 331 +745 4 0 388 185 336 611 +746 4 0 353 373 102 320 +747 4 0 373 102 314 353 +748 4 0 44 527 606 610 +749 4 0 74 110 84 353 +750 4 0 610 527 606 413 +751 4 0 325 341 375 98 +752 4 0 369 136 137 391 +753 4 0 169 354 342 313 +754 4 0 274 366 279 281 +755 4 0 281 366 279 276 +756 4 0 322 313 206 308 +757 4 0 414 289 344 385 +758 4 0 114 546 367 434 +759 4 0 367 391 434 369 +760 4 0 155 163 303 61 +761 4 0 47 620 527 44 +762 4 0 384 304 552 336 +763 4 0 384 310 306 336 +764 4 0 99 378 339 94 +765 4 0 506 94 378 99 +766 4 0 365 353 512 116 +767 4 0 378 99 418 506 +768 4 0 478 23 559 470 +769 4 0 328 86 633 128 +770 4 0 265 308 268 266 +771 4 0 268 308 263 266 +772 4 0 564 419 436 58 +773 4 0 460 75 564 65 +774 4 0 339 61 99 94 +775 4 0 518 564 65 460 +776 4 0 643 216 229 392 +777 4 0 342 88 76 67 +778 4 0 26 422 11 439 +779 4 0 26 440 439 571 +780 4 0 411 161 373 441 +781 4 0 442 467 412 10 +782 4 0 350 377 24 33 +783 4 0 225 409 217 223 +784 4 0 410 377 24 350 +785 4 0 24 350 33 335 +786 4 0 371 522 523 458 +787 4 0 278 324 273 276 +788 4 0 273 324 275 276 +789 4 0 170 354 172 184 +790 4 0 169 179 354 313 +791 4 0 607 16 24 580 +792 4 0 367 391 137 118 +793 4 0 35 620 37 527 +794 4 0 548 33 461 333 +795 4 0 414 385 344 294 +796 4 0 414 289 288 344 +797 4 0 65 64 484 454 +798 4 0 93 79 78 401 +799 4 0 375 382 358 90 +800 4 0 413 575 564 594 +801 4 0 187 181 368 189 +802 4 0 358 375 90 91 +803 4 0 275 276 324 323 +804 4 0 493 270 323 275 +805 4 0 532 323 276 275 +806 4 0 324 270 323 415 +807 4 0 275 323 324 270 +808 4 0 157 331 319 336 +809 4 0 454 339 61 338 +810 4 0 527 47 507 43 +811 4 0 74 87 110 353 +812 4 0 61 353 339 155 +813 4 0 444 445 618 379 +814 4 0 173 133 160 510 +815 4 0 352 604 468 347 +816 4 0 161 181 373 348 +817 4 0 23 335 470 33 +818 4 0 181 187 374 373 +819 4 0 29 35 28 33 +820 4 0 348 187 181 373 +821 4 0 562 10 412 447 +822 4 0 10 580 503 447 +823 4 0 399 351 34 38 +824 4 0 515 592 399 32 +825 4 0 434 112 637 474 +826 4 0 134 82 96 302 +827 4 0 224 230 233 212 +828 4 0 134 302 96 354 +829 4 0 302 354 162 96 +830 4 0 376 64 60 564 +831 4 0 606 640 589 45 +832 4 0 369 137 168 141 +833 4 0 113 361 583 136 +834 4 0 197 369 168 141 +835 4 0 12 7 4 14 +836 4 0 510 181 173 171 +837 4 0 61 339 353 94 +838 4 0 369 154 170 354 +839 4 0 404 607 24 21 +840 4 0 411 374 578 441 +841 4 0 500 186 189 480 +842 4 0 535 526 632 566 +843 4 0 628 441 497 483 +844 4 0 478 23 28 559 +845 4 0 28 335 559 23 +846 4 0 93 92 78 79 +847 4 0 554 473 631 453 +848 4 0 198 178 193 141 +849 4 0 187 444 209 500 +850 4 0 226 388 336 514 +851 4 0 287 464 285 528 +852 4 0 528 301 285 372 +853 4 0 497 629 426 373 +854 4 0 394 302 70 82 +855 4 0 64 61 454 75 +856 4 0 444 587 618 445 +857 4 0 467 458 371 523 +858 4 0 371 523 520 467 +859 4 0 371 520 551 467 +860 4 0 385 465 294 292 +861 4 0 468 604 345 476 +862 4 0 584 517 63 345 +863 4 0 176 136 137 369 +864 4 0 439 440 18 571 +865 4 0 490 26 11 439 +866 4 0 324 366 227 357 +867 4 0 606 413 419 436 +868 4 0 527 48 477 507 +869 4 0 527 477 48 457 +870 4 0 527 492 48 507 +871 4 0 527 626 48 492 +872 4 0 134 354 96 158 +873 4 0 62 64 489 60 +874 4 0 52 57 370 594 +875 4 0 326 52 55 564 +876 4 0 524 425 17 19 +877 4 0 373 441 161 540 +878 4 0 373 161 140 540 +879 4 0 66 326 55 58 +880 4 0 58 326 55 564 +881 4 0 310 309 336 270 +882 4 0 324 270 336 309 +883 4 0 157 336 185 331 +884 4 0 181 411 171 161 +885 4 0 640 589 641 606 +886 4 0 537 557 621 54 +887 4 0 282 285 340 288 +888 4 0 372 285 288 340 +889 4 0 382 100 98 341 +890 4 0 502 294 465 292 +891 4 0 43 34 351 38 +892 4 0 221 240 213 205 +893 4 0 438 240 205 213 +894 4 0 425 466 524 29 +895 4 0 354 302 146 108 +896 4 0 435 426 506 629 +897 4 0 497 506 426 629 +898 4 0 187 181 374 368 +899 4 0 517 79 614 345 +900 4 0 342 90 73 98 +901 4 0 180 141 178 152 +902 4 0 178 152 141 168 +903 4 0 193 180 141 178 +904 4 0 140 161 348 510 +905 4 0 9 442 13 362 +906 4 0 442 9 13 467 +907 4 0 408 505 503 580 +908 4 0 607 580 408 16 +909 4 0 327 289 414 385 +910 4 0 372 284 283 340 +911 4 0 359 89 526 566 +912 4 0 607 539 478 470 +913 4 0 140 373 125 348 +914 4 0 328 86 92 517 +915 4 0 527 47 44 606 +916 4 0 155 163 61 353 +917 4 0 367 391 118 434 +918 4 0 338 64 61 454 +919 4 0 64 338 484 454 +920 4 0 359 89 566 338 +921 4 0 489 526 566 64 +922 4 0 448 192 378 373 +923 4 0 350 39 377 33 +924 4 0 369 137 176 168 +925 4 0 377 350 553 39 +926 4 0 325 313 375 341 +927 4 0 340 288 625 282 +928 4 0 342 313 375 325 +929 4 0 524 466 19 20 +930 4 0 425 466 19 524 +931 4 0 348 395 186 202 +932 4 0 610 44 42 45 +933 4 0 409 433 217 223 +934 4 0 217 433 529 223 +935 4 0 582 375 471 115 +936 4 0 434 474 637 369 +937 4 0 382 375 471 582 +938 4 0 98 90 382 375 +939 4 0 382 100 90 98 +940 4 0 123 105 122 85 +941 4 0 122 85 105 80 +942 4 0 43 40 34 38 +943 4 0 369 474 361 136 +944 4 0 469 452 564 460 +945 4 0 46 41 527 457 +946 4 0 415 366 274 323 +947 4 0 191 387 316 438 +948 4 0 191 387 156 316 +949 4 0 434 391 474 369 +950 4 0 502 294 344 465 +951 4 0 502 294 292 293 +952 4 0 476 59 92 79 +953 4 0 306 309 319 336 +954 4 0 528 301 464 285 +955 4 0 301 282 464 285 +956 4 0 208 449 210 379 +957 4 0 210 379 220 208 +958 4 0 551 520 10 467 +959 4 0 359 89 339 106 +960 4 0 110 353 365 116 +961 4 0 353 511 110 365 +962 4 0 118 141 145 152 +963 4 0 34 28 466 29 +964 4 0 621 347 59 54 +965 4 0 59 621 79 347 +966 4 0 342 80 122 302 +967 4 0 369 123 154 342 +968 4 0 123 85 122 342 +969 4 0 122 342 85 80 +970 4 0 450 349 612 482 +971 4 0 564 55 436 413 +972 4 0 40 38 29 34 +973 4 0 606 641 413 436 +974 4 0 28 35 335 33 +975 4 0 34 25 32 29 +976 4 0 487 548 495 479 +977 4 0 187 209 196 348 +978 4 0 461 479 430 495 +979 4 0 311 513 509 186 +980 4 0 395 311 348 186 +981 4 0 187 196 209 444 +982 4 0 485 540 426 373 +983 4 0 21 580 24 447 +984 4 0 412 447 21 562 +985 4 0 412 562 21 446 +986 4 0 447 580 24 10 +987 4 0 46 527 610 413 +988 4 0 229 392 216 222 +989 4 0 323 281 366 274 +990 4 0 281 301 274 323 +991 4 0 599 625 429 282 +992 4 0 608 25 32 34 +993 4 0 372 288 284 340 +994 4 0 227 324 190 308 +995 4 0 373 196 348 187 +996 4 0 425 25 34 29 +997 4 0 628 448 373 591 +998 4 0 591 448 373 398 +999 4 0 477 43 41 527 +1000 4 0 80 71 81 302 +1001 4 0 457 477 41 527 +1002 4 0 647 487 430 479 +1003 4 0 628 373 497 441 +1004 4 0 578 628 441 374 +1005 4 0 410 24 335 350 +1006 4 0 393 311 160 150 +1007 4 0 367 118 137 141 +1008 4 0 343 488 356 396 +1009 4 0 87 72 61 58 +1010 4 0 488 588 356 396 +1011 4 0 476 54 59 347 +1012 4 0 94 353 61 77 +1013 4 0 110 353 87 107 +1014 4 0 251 245 322 201 +1015 4 0 245 179 322 201 +1016 4 0 11 422 486 14 +1017 4 0 287 588 464 528 +1018 4 0 10 467 412 551 +1019 4 0 13 551 412 467 +1020 4 0 371 467 551 13 +1021 4 0 551 10 8 412 +1022 4 0 113 164 361 136 +1023 4 0 425 25 15 26 +1024 4 0 140 348 125 160 +1025 4 0 451 588 528 286 +1026 4 0 180 152 145 141 +1027 4 0 607 16 539 470 +1028 4 0 374 570 400 373 +1029 4 0 373 374 556 400 +1030 4 0 374 373 556 628 +1031 4 0 441 628 578 483 +1032 4 0 497 642 418 629 +1033 4 0 167 89 106 339 +1034 4 0 346 440 390 521 +1035 4 0 369 123 342 375 +1036 4 0 583 382 498 361 +1037 4 0 564 75 72 61 +1038 4 0 564 61 64 75 +1039 4 0 345 517 79 92 +1040 4 0 533 529 223 222 +1041 4 0 498 582 576 375 +1042 4 0 575 376 609 49 +1043 4 0 412 10 8 447 +1044 4 0 561 472 549 468 +1045 4 0 239 322 252 231 +1046 4 0 397 12 4 14 +1047 4 0 367 369 434 576 +1048 4 0 206 313 322 179 +1049 4 0 322 179 313 354 +1050 4 0 12 2 4 7 +1051 4 0 346 638 26 608 +1052 4 0 66 87 57 58 +1053 4 0 72 58 564 61 +1054 4 0 322 207 231 239 +1055 4 0 201 354 322 207 +1056 4 0 239 255 322 201 +1057 4 0 533 402 529 222 +1058 4 0 60 518 564 65 +1059 4 0 11 486 12 14 +1060 4 0 118 168 141 152 +1061 4 0 60 376 564 518 +1062 4 0 576 375 582 115 +1063 4 0 515 34 399 351 +1064 4 0 334 564 64 363 +1065 4 0 311 331 150 305 +1066 4 0 473 538 597 519 +1067 4 0 564 594 575 475 +1068 4 0 36 30 432 410 +1069 4 0 343 396 356 279 +1070 4 0 281 279 356 396 +1071 4 0 281 274 301 356 +1072 4 0 486 7 14 422 +1073 4 0 642 153 585 629 +1074 4 0 153 642 628 629 +1075 4 0 503 447 8 10 +1076 4 0 461 430 620 416 +1077 4 0 493 270 275 280 +1078 4 0 275 493 532 323 +1079 4 0 532 493 282 323 +1080 4 0 461 495 430 416 +1081 4 0 493 532 280 275 +1082 4 0 389 381 47 413 +1083 4 0 49 413 626 527 +1084 4 0 500 189 186 181 +1085 4 0 498 382 582 375 +1086 4 0 410 30 24 377 +1087 4 0 30 410 36 377 +1088 4 0 366 265 279 272 +1089 4 0 608 34 32 31 +1090 4 0 527 40 43 38 +1091 4 0 46 527 41 38 +1092 4 0 43 527 38 41 +1093 4 0 597 639 7 486 +1094 4 0 306 298 336 331 +1095 4 0 11 26 15 543 +1096 4 0 554 11 15 543 +1097 4 0 416 430 620 649 +1098 4 0 291 290 364 327 +1099 4 0 637 498 375 361 +1100 4 0 39 548 33 461 +1101 4 0 422 634 25 543 +1102 4 0 583 582 382 113 +1103 4 0 367 114 118 141 +1104 4 0 473 422 11 554 +1105 4 0 178 197 168 141 +1106 4 0 375 369 123 115 +1107 4 0 91 123 115 375 +1108 4 0 377 350 36 553 +1109 4 0 173 181 516 186 +1110 4 0 110 95 107 87 +1111 4 0 353 107 163 87 +1112 4 0 46 527 42 610 +1113 4 0 500 209 348 202 +1114 4 0 334 61 564 57 +1115 4 0 510 103 140 161 +1116 4 0 160 104 140 133 +1117 4 0 486 11 473 422 +1118 4 0 336 611 331 514 +1119 4 0 576 434 637 369 +1120 4 0 29 466 524 20 +1121 4 0 366 279 265 258 +1122 4 0 366 279 258 274 +1123 4 0 89 484 338 454 +1124 4 0 462 621 568 534 +1125 4 0 133 104 140 103 +1126 4 0 462 534 568 531 +1127 4 0 521 440 390 563 +1128 4 0 383 440 563 390 +1129 4 0 141 154 170 369 +1130 4 0 141 193 369 170 +1131 4 0 173 181 510 516 +1132 4 0 348 510 181 516 +1133 4 0 324 366 276 272 +1134 4 0 415 324 366 323 +1135 4 0 477 527 507 43 +1136 4 0 26 25 440 346 +1137 4 0 430 333 42 479 +1138 4 0 460 452 564 75 +1139 4 0 31 515 32 592 +1140 4 0 181 189 187 500 +1141 4 0 389 527 413 47 +1142 4 0 413 389 626 527 +1143 4 0 376 590 49 575 +1144 4 0 331 611 185 508 +1145 4 0 223 392 407 219 +1146 4 0 223 233 392 219 +1147 4 0 538 648 597 519 +1148 4 0 597 648 538 486 +1149 4 0 557 537 568 499 +1150 4 0 553 39 461 416 +1151 4 0 290 528 451 287 +1152 4 0 554 453 332 560 +1153 4 0 601 467 458 9 +1154 4 0 623 525 535 566 +1155 4 0 566 525 535 526 +1156 4 0 378 106 431 418 +1157 4 0 53 496 352 347 +1158 4 0 564 300 419 72 +1159 4 0 564 452 300 72 +1160 4 0 2 6 7 486 +1161 4 0 421 451 528 286 +1162 4 0 451 528 588 287 +1163 4 0 409 595 433 491 +1164 4 0 79 621 78 401 +1165 4 0 401 621 78 555 +1166 4 0 78 537 555 621 +1167 4 0 599 340 282 301 +1168 4 0 493 599 282 301 +1169 4 0 430 620 42 333 +1170 4 0 565 498 112 637 +1171 4 0 583 498 112 565 +1172 4 0 599 429 536 282 +1173 4 0 599 625 459 429 +1174 4 0 543 554 332 15 +1175 4 0 474 112 637 565 +1176 4 0 364 290 528 327 +1177 4 0 548 461 479 333 +1178 4 0 461 333 430 479 +1179 4 0 383 390 346 440 +1180 4 0 65 60 64 564 +1181 4 0 65 64 75 564 +1182 4 0 383 638 346 390 +1183 4 0 380 468 614 549 +1184 4 0 532 282 276 323 +1185 4 0 157 331 504 150 +1186 4 0 89 454 338 339 +1187 4 0 167 454 89 339 +1188 4 0 8 5 10 551 +1189 4 0 5 520 10 551 +1190 4 0 492 626 545 389 +1191 4 0 389 626 545 469 +1192 4 0 37 33 35 29 +1193 4 0 615 568 499 557 +1194 4 0 500 186 480 202 +1195 4 0 54 56 53 496 +1196 4 0 294 295 291 385 +1197 4 0 295 291 385 327 +1198 4 0 295 294 292 385 +1199 4 0 474 637 361 565 +1200 4 0 497 373 426 540 +1201 4 0 40 29 28 34 +1202 4 0 535 525 581 526 +1203 4 0 328 92 79 517 +1204 4 0 496 56 352 604 +1205 4 0 459 536 646 493 +1206 4 0 459 429 624 536 +1207 4 0 493 536 280 532 +1208 4 0 25 346 26 608 +1209 4 0 351 399 41 38 +1210 4 0 43 41 38 351 +1211 4 0 527 413 47 606 +1212 4 0 308 252 322 231 +1213 4 0 308 255 322 252 +1214 4 0 256 231 252 308 +1215 4 0 256 308 259 247 +1216 4 0 21 30 24 410 +1217 4 0 21 30 562 24 +1218 4 0 315 621 555 568 +1219 4 0 217 219 223 407 +1220 4 0 225 223 219 233 +1221 4 0 407 217 529 223 +1222 4 0 381 452 300 564 +1223 4 0 595 635 433 491 +1224 4 0 414 385 291 327 +1225 4 0 416 39 461 495 +1226 4 0 461 39 548 495 +1227 4 0 461 548 479 495 +1228 4 0 301 282 281 464 +1229 4 0 301 282 285 340 +1230 4 0 315 621 568 462 +1231 4 0 372 289 288 285 +1232 4 0 289 288 285 414 +1233 4 0 431 153 106 378 +1234 4 0 55 641 589 436 +1235 4 0 651 572 638 608 +1236 4 0 564 452 72 75 +1237 4 0 573 534 567 613 +1238 4 0 567 645 600 534 +1239 4 0 499 568 577 537 +1240 4 0 414 327 291 364 +1241 4 0 561 549 614 468 +1242 4 0 338 489 566 64 +1243 4 0 89 484 489 338 +1244 4 0 385 294 465 344 +1245 4 0 445 196 444 209 +1246 4 0 209 550 444 427 +1247 4 0 490 14 11 12 +1248 4 0 490 18 14 12 +1249 4 0 597 648 486 7 +1250 4 0 486 639 7 422 +1251 4 0 639 473 597 631 +1252 4 0 529 491 616 533 +1253 4 0 435 320 125 373 +1254 4 0 616 491 529 541 +1255 4 0 497 628 642 629 +1256 4 0 46 52 413 602 +1257 4 0 623 359 566 338 +1258 4 0 497 506 629 418 +1259 4 0 99 359 623 338 +1260 4 0 65 64 454 75 +1261 4 0 209 617 550 427 +1262 4 0 86 328 144 128 +1263 4 0 570 187 374 368 +1264 4 0 403 86 633 328 +1265 4 0 601 522 458 523 +1266 4 0 604 352 472 56 +1267 4 0 273 312 319 324 +1268 4 0 380 614 63 549 +1269 4 0 561 549 63 614 +1270 4 0 623 525 566 359 +1271 4 0 359 525 566 526 +1272 4 0 566 89 526 489 +1273 4 0 113 382 358 471 +1274 4 0 582 471 382 113 +1275 4 0 523 467 458 601 +1276 4 0 268 308 260 263 +1277 4 0 374 628 556 578 +1278 4 0 498 582 382 583 +1279 4 0 586 645 534 557 +1280 4 0 361 176 369 136 +1281 4 0 277 356 274 279 +1282 4 0 576 637 375 369 +1283 4 0 637 375 369 361 +1284 4 0 373 556 569 400 +1285 4 0 556 373 569 628 +1286 4 0 447 562 24 21 +1287 4 0 47 492 527 507 +1288 4 0 495 39 548 487 +1289 4 0 572 608 651 650 +1290 4 0 541 619 542 574 +1291 4 0 27 562 21 30 +1292 4 0 21 446 562 27 +1293 4 0 517 328 614 79 +1294 4 0 545 530 622 575 +1295 4 0 522 371 523 558 +1296 4 0 523 371 520 558 +1297 4 0 471 91 115 375 +1298 4 0 578 127 628 556 +1299 4 0 127 153 628 556 +1300 4 0 641 413 55 52 +1301 4 0 55 564 436 58 +1302 4 0 564 334 57 594 +1303 4 0 55 641 436 413 +1304 4 0 575 413 49 594 +1305 4 0 15 17 596 560 +1306 4 0 521 440 563 571 +1307 4 0 632 581 62 526 +1308 4 0 285 372 301 340 +1309 4 0 290 451 528 421 +1310 4 0 326 57 564 58 +1311 4 0 205 212 241 204 +1312 4 0 564 452 469 381 +1313 4 0 239 322 207 201 +1314 4 0 223 392 529 407 +1315 4 0 381 564 413 469 +1316 4 0 395 513 311 186 +1317 4 0 389 469 413 626 +1318 4 0 136 361 583 565 +1319 4 0 586 645 567 534 +1320 4 0 32 25 608 346 +1321 4 0 369 367 137 141 +1322 4 0 469 575 545 622 +1323 4 0 593 543 634 422 +1324 4 0 373 569 628 591 +1325 4 0 556 569 153 628 +1326 4 0 196 187 373 570 +1327 4 0 167 454 339 155 +1328 4 0 590 626 575 530 +1329 4 0 536 493 282 532 +1330 4 0 133 140 160 510 +1331 4 0 376 363 64 564 +1332 4 0 209 427 444 587 +1333 4 0 571 440 563 383 +1334 4 0 498 375 576 637 +1335 4 0 531 534 568 579 +1336 4 0 534 568 557 621 +1337 4 0 218 392 643 238 +1338 4 0 568 555 577 537 +1339 4 0 475 609 363 49 +1340 4 0 363 609 475 564 +1341 4 0 393 311 150 305 +1342 4 0 19 425 17 596 +1343 4 0 596 17 603 560 +1344 4 0 522 428 371 558 +1345 4 0 127 628 497 483 +1346 4 0 492 48 545 626 +1347 4 0 21 607 24 580 +1348 4 0 132 117 318 128 +1349 4 0 633 132 547 142 +1350 4 0 437 381 419 413 +1351 4 0 419 381 437 300 +1352 4 0 173 181 186 171 +1353 4 0 405 613 600 534 +1354 4 0 632 526 62 64 +1355 4 0 489 484 64 338 +1356 4 0 600 54 53 621 +1357 4 0 29 20 28 466 +1358 4 0 20 28 466 443 +1359 4 0 49 48 626 590 +1360 4 0 63 345 614 380 +1361 4 0 584 345 63 380 +1362 4 0 470 607 559 478 +1363 4 0 28 23 22 20 +1364 4 0 478 23 22 28 +1365 4 0 473 422 554 631 +1366 4 0 555 537 568 621 +1367 4 0 18 490 14 439 +1368 4 0 596 17 19 603 +1369 4 0 571 440 18 521 +1370 4 0 542 491 616 541 +1371 4 0 534 568 615 557 +1372 4 0 534 568 579 615 +1373 4 0 392 222 229 238 +1374 4 0 626 48 530 590 +1375 4 0 238 406 229 423 +1376 4 0 629 585 642 418 +1377 4 0 418 506 629 378 +1378 4 0 378 431 629 418 +1379 4 0 153 448 628 591 +1380 4 0 591 569 628 153 +1381 4 0 550 209 500 627 +1382 4 0 515 31 32 34 +1383 4 0 209 627 550 617 +1384 4 0 569 556 153 400 +1385 4 0 645 621 557 54 +1386 4 0 529 491 533 223 +1387 4 0 601 1 458 522 +1388 4 0 522 601 1 3 +1389 4 0 359 339 99 106 +1390 4 0 338 99 359 339 +1391 4 0 49 575 626 413 +1392 4 0 473 597 631 453 +1393 4 0 605 564 518 460 +1394 4 0 222 392 402 529 +1395 4 0 113 382 583 361 +1396 4 0 33 335 28 23 +1397 4 0 370 52 594 46 +1398 4 0 408 505 580 607 +1399 4 0 413 640 602 641 +1400 4 0 630 376 564 609 +1401 4 0 49 376 609 363 +1402 4 0 363 376 609 564 +1403 4 0 393 456 311 305 +1404 4 0 218 221 386 643 +1405 4 0 643 386 423 221 +1406 4 0 141 123 369 367 +1407 4 0 498 382 375 361 +1408 4 0 474 637 369 361 +1409 4 0 558 371 520 551 +1410 4 0 558 428 371 551 +1411 4 0 374 441 411 373 +1412 4 0 422 25 26 543 +1413 4 0 25 17 15 634 +1414 4 0 606 44 610 45 +1415 4 0 367 115 369 576 +1416 4 0 367 576 546 115 +1417 4 0 636 573 567 613 +1418 4 0 615 51 579 573 +1419 4 0 50 51 615 636 +1420 4 0 55 413 564 52 +1421 4 0 594 52 413 46 +1422 4 0 564 326 52 57 +1423 4 0 367 434 546 576 +1424 4 0 208 449 379 445 +1425 4 0 379 445 544 208 +1426 4 0 26 439 440 25 +1427 4 0 622 575 605 469 +1428 4 0 636 586 567 573 +1429 4 0 573 586 567 534 +1430 4 0 599 625 340 283 +1431 4 0 605 630 518 564 +1432 4 0 171 510 181 161 +1433 4 0 32 29 38 34 +1434 4 0 402 216 392 222 +1435 4 0 223 222 392 238 +1436 4 0 389 492 527 47 +1437 4 0 389 492 626 527 +1438 4 0 577 555 78 537 +1439 4 0 315 621 401 555 +1440 4 0 15 598 634 560 +1441 4 0 634 17 15 560 +1442 4 0 481 142 328 633 +1443 4 0 128 328 144 138 +1444 4 0 413 610 640 606 +1445 4 0 640 606 610 45 +1446 4 0 379 449 444 445 +1447 4 0 187 449 196 444 +1448 4 0 445 449 444 196 +1449 4 0 605 564 460 469 +1450 4 0 575 564 605 469 +1451 4 0 541 200 619 574 +1452 4 0 564 436 419 413 +1453 4 0 517 482 63 614 +1454 4 0 154 369 141 123 +1455 4 0 583 498 565 361 +1456 4 0 498 361 637 565 +1457 4 0 622 530 630 575 +1458 4 0 21 30 432 27 +1459 4 0 173 510 160 516 +1460 4 0 311 160 348 516 +1461 4 0 485 140 540 373 +1462 4 0 21 505 580 447 +1463 4 0 490 26 439 571 +1464 4 0 379 544 220 208 +1465 4 0 348 516 181 186 +1466 4 0 186 509 311 516 +1467 4 0 209 202 627 617 +1468 4 0 433 635 529 491 +1469 4 0 430 42 620 44 +1470 4 0 649 430 620 44 +1471 4 0 529 635 541 491 +1472 4 0 404 24 410 21 +1473 4 0 404 410 24 335 +1474 4 0 89 338 359 339 +1475 4 0 450 328 482 517 +1476 4 0 517 328 482 614 +1477 4 0 78 59 537 621 +1478 4 0 588 396 281 356 +1479 4 0 286 488 588 356 +1480 4 0 424 543 593 422 +1481 4 0 463 607 408 16 +1482 4 0 389 381 413 469 +1483 4 0 413 469 575 626 +1484 4 0 626 469 575 545 +1485 4 0 554 11 543 422 +1486 4 0 459 624 646 536 +1487 4 0 332 543 593 424 +1488 4 0 631 554 424 422 +1489 4 0 153 431 629 378 +1490 4 0 545 48 530 626 +1491 4 0 626 530 545 575 +1492 4 0 59 621 78 79 +1493 4 0 160 510 348 516 +1494 4 0 626 590 575 49 +1495 4 0 576 434 112 637 +1496 4 0 498 576 112 637 +1497 4 0 346 651 638 608 +1498 4 0 13 442 412 362 +1499 4 0 13 467 412 442 +1500 4 0 132 142 633 128 +1501 4 0 184 180 172 170 +1502 4 0 631 332 424 554 +1503 4 0 531 573 579 51 +1504 4 0 521 571 563 18 +1505 4 0 599 625 282 340 +1506 4 0 622 630 605 575 +1507 4 0 562 442 362 412 +1508 4 0 193 180 170 141 +1509 4 0 50 644 636 615 +1510 4 0 443 466 20 19 +1511 4 0 616 542 533 491 +1512 4 0 413 594 564 52 +1513 4 0 621 53 600 405 +1514 4 0 362 562 446 27 +1515 4 0 403 547 321 481 +1516 4 0 403 481 321 329 +1517 4 0 562 442 412 10 +1518 4 0 493 459 536 599 +1519 4 0 493 599 536 282 +1520 4 0 450 86 328 517 +1521 4 0 413 602 610 46 +1522 4 0 29 23 28 20 +1523 4 0 223 409 433 491 +1524 4 0 621 59 537 54 +1525 4 0 13 362 412 446 +1526 4 0 439 422 11 14 +1527 4 0 639 473 631 422 +1528 4 0 450 612 584 517 +1529 4 0 450 482 612 517 +1530 4 0 413 641 602 52 +1531 4 0 447 10 24 562 +1532 4 0 531 573 534 579 +1533 4 0 380 345 468 604 +1534 4 0 587 427 444 618 +1535 4 0 613 567 600 534 +1536 4 0 218 386 238 643 +1537 4 0 643 238 423 386 +1538 4 0 347 496 352 604 +1539 4 0 63 345 517 614 +1540 4 0 584 612 63 517 +1541 4 0 629 431 585 418 +1542 4 0 153 431 585 629 +1543 4 0 463 539 478 607 +1544 4 0 463 539 607 16 +1545 4 0 564 609 475 575 +1546 4 0 533 529 402 616 +1547 4 0 376 630 564 518 +1548 4 0 645 54 600 621 +1549 4 0 380 468 472 604 +1550 4 0 604 468 472 352 +1551 4 0 380 468 549 472 +1552 4 0 570 187 373 374 +1553 4 0 606 413 641 640 +1554 4 0 413 610 602 640 +1555 4 0 458 467 13 9 +1556 4 0 467 458 13 371 +1557 4 0 11 422 26 543 +1558 4 0 25 17 425 15 +1559 4 0 646 536 280 493 +1560 4 0 646 624 280 536 +1561 4 0 647 430 44 42 +1562 4 0 618 544 220 379 +1563 4 0 648 6 486 7 +1564 4 0 648 6 538 486 +1565 4 0 403 633 547 481 +1566 4 0 403 328 633 481 +1567 4 0 483 127 628 578 +1568 4 0 486 7 12 14 +1569 4 0 53 56 352 496 +1570 4 0 340 288 284 625 +1571 4 0 283 340 284 625 +1572 4 0 561 352 472 468 +1573 4 0 86 450 328 403 +1574 4 0 329 403 481 328 +1575 4 0 455 288 284 372 +1576 4 0 501 288 284 455 +1577 4 0 376 530 575 630 +1578 4 0 630 376 609 575 +1579 4 0 430 479 42 647 +1580 4 0 621 405 600 534 +1581 4 0 22 28 20 443 +1582 4 0 643 238 229 423 +1583 4 0 481 633 547 142 +1584 4 0 558 428 551 652 +1585 4 0 509 611 331 508 +1586 4 0 513 514 331 611 +1587 4 0 509 513 331 611 +1588 4 0 601 9 1 3 +1589 4 0 289 288 344 501 +1590 4 0 515 32 399 34 +1591 4 0 403 321 349 329 +1592 4 0 392 229 643 238 +1593 4 0 618 445 544 379 +1594 4 0 618 587 544 445 +1595 4 0 531 613 534 573 +1596 4 0 629 153 448 628 +1597 4 0 538 473 597 486 +1598 4 0 597 473 639 486 +1599 4 0 650 31 608 346 +1600 4 0 607 505 580 21 +1601 4 0 288 455 289 372 +1602 4 0 289 455 288 501 +1603 4 0 376 530 590 575 +1604 4 0 49 594 475 575 +1605 4 0 356 279 281 274 +1606 4 0 550 209 444 500 +1607 4 0 362 412 446 562 +1608 4 0 529 433 491 223 +1609 4 0 455 372 284 283 +1610 4 0 465 501 455 289 +1611 4 0 465 289 344 501 +1612 4 0 445 209 444 587 +1613 4 0 153 642 127 628 +1614 4 0 294 385 291 414 +1615 4 0 283 625 459 599 +1616 4 0 613 531 51 573 +1617 4 0 636 573 613 51 +1618 4 0 557 621 568 537 +1619 4 0 558 551 520 5 +1620 4 0 500 209 202 627 +1621 4 0 635 200 541 574 +1622 4 0 595 200 635 574 +1623 4 0 558 652 551 5 +1624 4 0 534 579 573 615 +1625 4 0 605 575 630 564 +1626 4 0 31 346 32 608 +1627 4 0 631 424 639 422 +1628 4 0 383 346 638 26 +1629 4 0 469 575 564 413 +1630 4 0 15 560 332 598 +1631 4 0 15 554 332 560 +1632 4 0 586 557 534 615 +1633 4 0 573 586 534 615 +1634 4 0 332 543 598 593 +1635 4 0 543 332 598 15 +1636 4 0 609 575 564 630 +1637 4 0 554 631 332 453 +1638 4 0 424 554 543 422 +1639 4 0 608 346 651 650 +1640 4 0 487 495 430 479 +1641 4 0 645 621 534 557 +1642 4 0 645 621 600 534 +1643 4 0 542 491 541 574 +1644 4 0 541 635 574 491 +1645 4 0 636 644 586 573 +1646 4 0 573 586 615 644 +1647 4 0 543 634 598 593 +1648 4 0 497 127 642 628 +1649 4 0 598 543 15 634 +1650 4 0 25 15 543 634 +1651 4 0 473 519 597 453 +1652 4 0 595 574 635 491 +1653 4 0 636 51 615 573 +1654 4 0 644 573 636 615 +$EndElements +$ElementData +1 +"color" +1 +0.0 +3 +0 +1 +1654 +1 7.56199 +2 4.86806 +3 4.40144 +4 6.42934 +5 4.22059 +6 5.73014 +7 6.38728 +8 6.65278 +9 6.11566 +10 8.59831 +11 4.59846 +12 3.75402 +13 4.81655 +14 5.303 +15 4.23688 +16 4.44352 +17 9.61146 +18 4.02007 +19 6.55381 +20 4.32183 +21 3.77651 +22 4.28126 +23 4.67035 +24 4.25302 +25 3.24949 +26 3.81682 +27 3.6786 +28 5.26567 +29 5.75883 +30 4.40013 +31 4.8604 +32 3.88159 +33 3.62912 +34 6.09732 +35 6.23606 +36 6.81931 +37 3.98474 +38 5.09313 +39 7.92162 +40 5.91342 +41 5.89822 +42 7.79576 +43 3.26766 +44 6.40478 +45 3.30998 +46 5.75804 +47 4.44341 +48 5.56712 +49 7.92901 +50 7.32341 +51 4.11488 +52 7.27876 +53 4.46523 +54 4.41017 +55 4.24074 +56 5.18865 +57 3.67411 +58 3.93323 +59 6.27803 +60 5.7046 +61 5.43246 +62 6.62422 +63 6.87791 +64 4.8315 +65 4.41484 +66 3.44597 +67 4.80585 +68 4.76576 +69 5.09151 +70 3.90176 +71 3.98978 +72 7.05842 +73 5.79771 +74 5.72113 +75 5.39406 +76 8.36837 +77 6.57885 +78 3.81664 +79 5.04602 +80 5.13045 +81 4.17786 +82 4.12193 +83 5.498 +84 3.9477 +85 4.17729 +86 4.53085 +87 4.87674 +88 5.63865 +89 4.91132 +90 5.42233 +91 7.2101 +92 6.62552 +93 5.99626 +94 5.99827 +95 4.64279 +96 4.40763 +97 7.74874 +98 4.60244 +99 4.55322 +100 3.87632 +101 4.43066 +102 3.5908 +103 4.4961 +104 4.6942 +105 6.85876 +106 6.09827 +107 5.34771 +108 3.88554 +109 4.99917 +110 5.07909 +111 5.16529 +112 6.2445 +113 4.05386 +114 4.0937 +115 4.62717 +116 4.31849 +117 3.26285 +118 3.35407 +119 3.68025 +120 5.5668 +121 4.22251 +122 4.99967 +123 4.02172 +124 7.95474 +125 6.88951 +126 5.11647 +127 3.62751 +128 3.75947 +129 5.71937 +130 4.65378 +131 4.22097 +132 3.54665 +133 4.0164 +134 4.14403 +135 5.88228 +136 3.88365 +137 4.9027 +138 3.88649 +139 3.94684 +140 5.61741 +141 4.86852 +142 4.25794 +143 7.6941 +144 4.73617 +145 3.12373 +146 4.88928 +147 3.62576 +148 4.16485 +149 3.9426 +150 3.46852 +151 6.77747 +152 5.33702 +153 6.56503 +154 5.80932 +155 6.15413 +156 6.85355 +157 4.14906 +158 6.14933 +159 6.69641 +160 3.64734 +161 9.61926 +162 4.84044 +163 6.90865 +164 3.44809 +165 7.79131 +166 4.2801 +167 3.52051 +168 5.45391 +169 3.39718 +170 4.71838 +171 3.97902 +172 6.18658 +173 4.17284 +174 3.92603 +175 6.61929 +176 4.47741 +177 5.4168 +178 4.66072 +179 6.78272 +180 8.92575 +181 3.81346 +182 3.82779 +183 3.59616 +184 4.4729 +185 4.12509 +186 9.13405 +187 4.3469 +188 4.17304 +189 3.37722 +190 4.22285 +191 3.89981 +192 3.56114 +193 5.07249 +194 5.73119 +195 3.31977 +196 7.91262 +197 4.91172 +198 4.3087 +199 4.15402 +200 7.6821 +201 4.41955 +202 4.64581 +203 4.16326 +204 7.51723 +205 6.23256 +206 4.63327 +207 4.85318 +208 6.48807 +209 3.61821 +210 5.09043 +211 8.53276 +212 6.52094 +213 3.90421 +214 4.42601 +215 3.83625 +216 5.54714 +217 3.51603 +218 3.84227 +219 5.7805 +220 5.82631 +221 4.20829 +222 5.28021 +223 4.00498 +224 6.02503 +225 5.06898 +226 5.05237 +227 4.69681 +228 4.59421 +229 4.21961 +230 4.26009 +231 5.25661 +232 6.12045 +233 4.26478 +234 3.42011 +235 3.96254 +236 5.39782 +237 5.34452 +238 5.57074 +239 3.58786 +240 5.48832 +241 5.04805 +242 6.99507 +243 4.86669 +244 8.67723 +245 4.42583 +246 6.08779 +247 8.30081 +248 4.11458 +249 7.33372 +250 4.37632 +251 6.55974 +252 4.06411 +253 7.65217 +254 4.98446 +255 7.00166 +256 9.18261 +257 3.97417 +258 3.76504 +259 4.45173 +260 3.78705 +261 8.85178 +262 5.99438 +263 3.68369 +264 4.64732 +265 5.79147 +266 6.364 +267 5.03453 +268 4.96944 +269 4.75356 +270 3.20622 +271 4.24018 +272 4.41709 +273 4.21315 +274 4.38612 +275 6.51163 +276 5.01322 +277 5.46653 +278 3.97587 +279 6.44458 +280 4.97667 +281 5.55967 +282 5.85158 +283 5.0027 +284 3.48534 +285 6.58618 +286 4.80285 +287 5.94949 +288 4.82903 +289 7.5367 +290 5.70127 +291 7.09932 +292 5.78603 +293 5.97275 +294 3.8847 +295 7.18803 +296 4.24715 +297 6.96264 +298 7.0952 +299 4.63648 +300 6.55609 +301 5.16808 +302 5.24241 +303 3.54707 +304 4.3924 +305 4.0213 +306 4.62658 +307 4.81065 +308 4.56642 +309 6.50736 +310 4.75308 +311 3.8215 +312 3.41325 +313 4.08294 +314 4.91393 +315 5.30757 +316 7.02954 +317 5.24187 +318 4.13738 +319 6.58547 +320 3.70239 +321 3.67817 +322 4.58162 +323 5.24492 +324 4.86733 +325 4.91221 +326 4.2757 +327 5.39939 +328 4.61598 +329 8.42673 +330 6.14168 +331 4.57608 +332 3.81451 +333 4.29124 +334 4.12792 +335 5.02872 +336 5.23399 +337 3.38677 +338 4.50817 +339 5.28311 +340 5.64442 +341 4.71327 +342 6.09192 +343 4.17098 +344 7.35127 +345 5.55052 +346 8.62264 +347 7.92427 +348 4.62414 +349 5.61806 +350 5.34776 +351 6.86714 +352 4.07043 +353 3.76518 +354 3.52133 +355 4.0364 +356 4.23061 +357 5.51497 +358 5.34338 +359 5.2446 +360 3.66377 +361 3.61536 +362 4.93218 +363 5.91732 +364 3.99037 +365 6.86673 +366 4.57754 +367 4.54417 +368 3.49705 +369 3.68222 +370 4.05441 +371 3.28484 +372 3.86728 +373 6.47469 +374 3.8287 +375 4.21948 +376 6.50072 +377 5.2599 +378 5.46621 +379 3.90163 +380 8.20664 +381 5.20216 +382 5.3226 +383 4.03878 +384 8.93219 +385 6.79859 +386 5.0444 +387 4.38992 +388 6.97679 +389 3.69486 +390 3.64051 +391 3.67985 +392 6.23422 +393 3.30838 +394 7.50667 +395 3.94216 +396 6.5134 +397 8.60865 +398 4.39139 +399 3.46463 +400 3.90001 +401 4.26802 +402 3.71403 +403 3.59913 +404 3.15595 +405 4.92885 +406 9.80662 +407 3.63884 +408 3.80748 +409 5.15094 +410 6.35325 +411 4.20196 +412 5.86833 +413 5.91247 +414 3.313 +415 3.37645 +416 4.89339 +417 5.19552 +418 6.53485 +419 7.98558 +420 3.6091 +421 4.05488 +422 4.29978 +423 4.68265 +424 8.03386 +425 5.59842 +426 4.70185 +427 3.61697 +428 5.69205 +429 7.16982 +430 4.13106 +431 3.56492 +432 4.22082 +433 4.55629 +434 4.58142 +435 5.53457 +436 6.93426 +437 4.80377 +438 3.84526 +439 3.94317 +440 3.45505 +441 5.16289 +442 3.25289 +443 3.95152 +444 5.40892 +445 6.95209 +446 4.15315 +447 5.02186 +448 4.01812 +449 3.96462 +450 7.14857 +451 4.97123 +452 4.79327 +453 4.80934 +454 7.58936 +455 4.07601 +456 4.83387 +457 4.20561 +458 4.19693 +459 4.28828 +460 6.64926 +461 6.10328 +462 5.14523 +463 3.29956 +464 7.82612 +465 6.51338 +466 5.14228 +467 6.36966 +468 4.00039 +469 5.25401 +470 4.90217 +471 3.91685 +472 4.04775 +473 3.71452 +474 4.00893 +475 6.15397 +476 4.73995 +477 4.49103 +478 6.01817 +479 4.51129 +480 4.45673 +481 4.53029 +482 4.39765 +483 4.84946 +484 4.41482 +485 5.22789 +486 4.83751 +487 4.52841 +488 4.37907 +489 4.53931 +490 3.94812 +491 5.60107 +492 7.82411 +493 6.10887 +494 3.61105 +495 6.22222 +496 5.87689 +497 4.37764 +498 5.74756 +499 5.41576 +500 3.94004 +501 5.49027 +502 4.62278 +503 5.90077 +504 3.72543 +505 8.58284 +506 9.99379 +507 3.93429 +508 7.00354 +509 3.34162 +510 6.26251 +511 4.5708 +512 4.61934 +513 6.10199 +514 7.60203 +515 3.49142 +516 6.17078 +517 5.25425 +518 6.30042 +519 5.72046 +520 4.47283 +521 4.83221 +522 4.41013 +523 5.97733 +524 3.99931 +525 4.76894 +526 3.74452 +527 6.2368 +528 4.09343 +529 6.26363 +530 6.83661 +531 3.96425 +532 3.43579 +533 5.77657 +534 5.34581 +535 4.68041 +536 4.37814 +537 5.99737 +538 5.3648 +539 5.4205 +540 4.22935 +541 5.82056 +542 3.98684 +543 3.28936 +544 4.1958 +545 4.33791 +546 4.85201 +547 5.22988 +548 6.51603 +549 4.38544 +550 4.03691 +551 4.28065 +552 7.54771 +553 5.3477 +554 3.98013 +555 3.65612 +556 3.6305 +557 4.96827 +558 7.0639 +559 5.12306 +560 5.26116 +561 3.98468 +562 4.06433 +563 4.43174 +564 9.65465 +565 4.48661 +566 7.06711 +567 6.01908 +568 5.78751 +569 6.07332 +570 8.58829 +571 7.11434 +572 3.46196 +573 5.46102 +574 6.3086 +575 5.34819 +576 6.91082 +577 4.47437 +578 7.81942 +579 6.82906 +580 4.72318 +581 4.06215 +582 9.60519 +583 5.3436 +584 4.7691 +585 4.475 +586 5.84693 +587 5.8161 +588 4.01326 +589 8.52049 +590 6.06203 +591 3.94 +592 6.42148 +593 6.28834 +594 4.88767 +595 7.62703 +596 7.56987 +597 5.54109 +598 4.11926 +599 6.37613 +600 4.92981 +601 4.80206 +602 3.26213 +603 6.37042 +604 5.17572 +605 3.76555 +606 5.26092 +607 4.19725 +608 3.19057 +609 5.88572 +610 5.22575 +611 3.782 +612 4.38116 +613 8.53952 +614 4.30787 +615 4.10562 +616 7.62857 +617 5.65392 +618 5.96086 +619 4.91053 +620 6.14863 +621 5.91276 +622 4.27409 +623 5.55369 +624 4.8645 +625 4.77293 +626 3.55957 +627 4.11882 +628 3.68402 +629 6.55336 +630 5.93665 +631 6.29134 +632 5.06148 +633 6.32722 +634 3.56814 +635 4.97852 +636 5.319 +637 7.67988 +638 4.9724 +639 3.58948 +640 3.2273 +641 4.94275 +642 6.132 +643 4.23477 +644 3.8824 +645 6.47761 +646 5.83872 +647 6.52367 +648 9.09261 +649 4.02275 +650 4.5423 +651 3.77518 +652 9.34733 +653 4.29857 +654 3.53165 +655 3.69875 +656 8.91855 +657 8.27777 +658 4.2927 +659 5.44146 +660 4.88306 +661 4.61662 +662 4.66585 +663 4.08773 +664 5.47614 +665 4.82537 +666 5.34588 +667 5.09433 +668 4.74203 +669 4.80349 +670 5.17033 +671 5.55982 +672 5.85245 +673 8.50255 +674 5.05679 +675 8.2833 +676 4.20019 +677 6.65706 +678 5.50201 +679 3.83497 +680 8.04853 +681 3.98407 +682 4.14575 +683 4.40359 +684 3.83137 +685 7.5115 +686 4.55691 +687 5.02113 +688 4.10109 +689 3.2165 +690 6.76792 +691 7.39527 +692 5.09019 +693 4.66208 +694 4.89628 +695 3.82454 +696 7.89338 +697 4.34543 +698 4.53367 +699 4.2245 +700 7.97378 +701 5.36364 +702 5.48083 +703 5.18437 +704 7.54515 +705 8.01303 +706 6.9711 +707 5.10957 +708 4.65648 +709 4.17603 +710 3.95182 +711 4.30453 +712 4.83791 +713 5.75603 +714 6.26297 +715 4.26312 +716 4.92191 +717 6.49723 +718 5.39117 +719 7.63936 +720 3.8902 +721 5.26165 +722 3.56636 +723 5.80111 +724 8.11139 +725 6.99287 +726 6.0905 +727 4.48145 +728 6.29626 +729 6.41609 +730 4.82834 +731 4.30295 +732 5.95249 +733 9.1162 +734 7.17952 +735 4.41636 +736 7.00516 +737 5.38428 +738 4.57018 +739 5.16323 +740 6.21328 +741 3.84546 +742 8.92755 +743 4.95277 +744 5.60229 +745 4.74588 +746 4.39131 +747 3.53583 +748 4.71464 +749 3.85774 +750 4.32924 +751 4.21807 +752 5.56949 +753 3.92575 +754 4.08047 +755 4.19341 +756 5.43269 +757 5.08675 +758 7.55608 +759 4.60229 +760 5.26588 +761 6.53396 +762 6.09301 +763 8.49182 +764 3.65278 +765 3.7977 +766 4.72003 +767 5.07267 +768 5.39706 +769 5.74691 +770 7.17011 +771 4.60288 +772 6.53685 +773 5.03197 +774 4.75913 +775 5.21044 +776 8.20214 +777 5.1994 +778 5.72262 +779 5.56165 +780 5.11548 +781 4.91619 +782 4.4872 +783 5.68936 +784 4.47124 +785 5.13239 +786 3.56721 +787 6.21762 +788 7.03673 +789 4.75488 +790 6.58105 +791 6.02163 +792 4.0573 +793 5.61253 +794 4.57518 +795 6.37637 +796 4.44356 +797 4.71151 +798 7.569 +799 4.14096 +800 5.59666 +801 4.97895 +802 3.58641 +803 3.31542 +804 5.39692 +805 4.83649 +806 3.97031 +807 5.44832 +808 4.02433 +809 3.60805 +810 5.34786 +811 3.58587 +812 6.69862 +813 3.32895 +814 4.09119 +815 4.58371 +816 3.80674 +817 6.44114 +818 6.223 +819 4.0441 +820 4.80123 +821 4.30222 +822 6.44328 +823 5.35506 +824 6.92359 +825 3.89947 +826 6.49231 +827 4.93294 +828 4.30558 +829 6.36489 +830 6.66548 +831 4.33778 +832 4.17984 +833 5.47755 +834 6.30491 +835 4.8866 +836 3.97457 +837 5.46085 +838 9.49042 +839 5.90533 +840 4.86468 +841 6.77968 +842 4.50722 +843 6.47377 +844 6.71684 +845 7.28311 +846 4.96895 +847 4.62845 +848 4.76509 +849 4.94072 +850 6.06047 +851 5.03461 +852 4.02971 +853 6.54434 +854 6.22769 +855 4.93337 +856 3.68803 +857 3.53863 +858 3.91408 +859 5.65137 +860 7.37176 +861 4.59552 +862 6.93334 +863 3.44661 +864 6.33348 +865 5.02479 +866 5.35196 +867 4.49256 +868 4.90908 +869 5.13244 +870 6.53011 +871 6.74559 +872 6.30754 +873 4.22522 +874 5.22566 +875 4.48669 +876 6.19697 +877 5.32891 +878 5.90513 +879 5.26841 +880 4.69307 +881 6.53259 +882 5.37303 +883 4.84613 +884 6.84862 +885 8.57067 +886 4.51242 +887 4.09543 +888 3.96732 +889 3.54212 +890 7.13459 +891 3.96056 +892 3.53356 +893 7.88643 +894 3.71017 +895 4.50089 +896 6.13237 +897 9.12911 +898 5.99732 +899 4.20221 +900 5.07845 +901 7.39265 +902 3.4358 +903 6.92631 +904 6.19262 +905 8.37263 +906 3.90019 +907 5.27365 +908 8.43827 +909 4.30468 +910 7.89174 +911 4.55601 +912 5.99339 +913 3.9157 +914 6.4819 +915 5.12264 +916 4.56214 +917 4.68284 +918 3.62525 +919 5.50492 +920 3.3911 +921 5.44747 +922 5.1212 +923 3.91631 +924 4.09731 +925 3.90953 +926 3.24567 +927 3.84614 +928 3.16043 +929 5.57228 +930 5.27177 +931 4.70165 +932 6.21956 +933 6.82471 +934 4.75076 +935 5.36529 +936 7.32308 +937 5.56332 +938 4.4607 +939 4.55218 +940 4.41271 +941 4.16343 +942 3.60628 +943 5.64808 +944 5.0414 +945 4.07399 +946 8.06578 +947 5.13059 +948 3.32765 +949 6.87378 +950 6.8715 +951 5.34151 +952 7.4087 +953 4.97386 +954 4.34552 +955 4.26796 +956 4.19602 +957 3.42375 +958 5.85754 +959 5.66926 +960 8.16791 +961 5.85989 +962 5.27303 +963 4.04843 +964 3.73455 +965 6.69521 +966 3.19527 +967 5.41381 +968 4.9373 +969 3.34371 +970 5.277 +971 5.14515 +972 4.27359 +973 3.45159 +974 4.18209 +975 3.97173 +976 6.6748 +977 5.48345 +978 5.03449 +979 6.2847 +980 4.28563 +981 4.42304 +982 8.30151 +983 8.10918 +984 5.2181 +985 6.07928 +986 7.4987 +987 3.86094 +988 7.79415 +989 4.1437 +990 4.22013 +991 4.84238 +992 4.18954 +993 4.63546 +994 5.03533 +995 5.68754 +996 3.66053 +997 4.99215 +998 3.9023 +999 6.64228 +1000 3.66927 +1001 7.59005 +1002 7.84943 +1003 6.12621 +1004 4.28124 +1005 5.25678 +1006 4.49358 +1007 3.83982 +1008 4.1934 +1009 4.15133 +1010 5.9278 +1011 6.99563 +1012 5.9841 +1013 8.90109 +1014 7.652 +1015 7.06981 +1016 4.2989 +1017 4.43713 +1018 3.94864 +1019 5.25543 +1020 5.67571 +1021 4.55211 +1022 5.55705 +1023 4.35115 +1024 3.53053 +1025 4.95254 +1026 5.0626 +1027 5.91199 +1028 3.64351 +1029 4.37971 +1030 6.08977 +1031 8.17508 +1032 9.08688 +1033 6.27308 +1034 5.95361 +1035 5.76509 +1036 4.96722 +1037 5.54433 +1038 4.46812 +1039 5.33303 +1040 6.1708 +1041 6.72636 +1042 5.29678 +1043 4.55251 +1044 8.94976 +1045 3.51383 +1046 9.65923 +1047 5.82992 +1048 4.65022 +1049 4.9202 +1050 5.80657 +1051 3.98189 +1052 5.41173 +1053 4.62405 +1054 3.74779 +1055 3.72462 +1056 4.19243 +1057 8.98073 +1058 5.19122 +1059 4.03261 +1060 3.37577 +1061 5.38447 +1062 7.73223 +1063 8.13835 +1064 4.25916 +1065 4.74505 +1066 7.41008 +1067 7.34217 +1068 4.67887 +1069 7.30568 +1070 4.68001 +1071 4.1343 +1072 4.30236 +1073 4.91304 +1074 3.81816 +1075 4.33604 +1076 7.30661 +1077 3.71466 +1078 5.48295 +1079 5.02695 +1080 5.64749 +1081 4.97985 +1082 5.0635 +1083 4.18982 +1084 6.63653 +1085 6.50817 +1086 4.06997 +1087 4.6217 +1088 3.9456 +1089 5.86381 +1090 4.34958 +1091 4.72955 +1092 7.68562 +1093 4.76352 +1094 4.38867 +1095 7.24025 +1096 8.56583 +1097 7.12327 +1098 7.63126 +1099 4.98995 +1100 5.51299 +1101 6.22274 +1102 8.55485 +1103 4.67541 +1104 5.56093 +1105 4.11592 +1106 5.39012 +1107 4.91738 +1108 4.55802 +1109 9.81191 +1110 9.03824 +1111 4.91096 +1112 5.68686 +1113 5.43295 +1114 4.5376 +1115 7.76145 +1116 6.56722 +1117 5.56414 +1118 6.48512 +1119 7.08636 +1120 4.86379 +1121 5.06374 +1122 4.43781 +1123 6.37562 +1124 8.00607 +1125 5.72785 +1126 7.44421 +1127 8.55665 +1128 5.86133 +1129 9.30702 +1130 5.39706 +1131 9.72751 +1132 3.48947 +1133 4.01753 +1134 6.24749 +1135 5.18517 +1136 3.7291 +1137 5.12041 +1138 5.72019 +1139 8.40329 +1140 4.29092 +1141 6.32703 +1142 4.81643 +1143 6.2805 +1144 8.28778 +1145 6.11067 +1146 4.67958 +1147 6.84822 +1148 6.91117 +1149 8.73063 +1150 5.19026 +1151 8.76106 +1152 7.46817 +1153 4.01789 +1154 4.79286 +1155 4.32607 +1156 8.23324 +1157 4.8066 +1158 6.2838 +1159 6.4227 +1160 9.33195 +1161 4.68307 +1162 6.92146 +1163 6.30771 +1164 7.57291 +1165 7.22122 +1166 6.39772 +1167 5.60827 +1168 3.81708 +1169 3.25156 +1170 8.08526 +1171 7.77888 +1172 4.56788 +1173 8.09687 +1174 3.49101 +1175 4.88315 +1176 9.9666 +1177 5.09136 +1178 4.89489 +1179 8.84418 +1180 4.97986 +1181 5.33513 +1182 5.84621 +1183 3.85303 +1184 4.81127 +1185 7.16765 +1186 5.06141 +1187 7.20188 +1188 4.7328 +1189 5.06946 +1190 3.66104 +1191 4.29874 +1192 3.89884 +1193 6.80851 +1194 5.53224 +1195 7.4339 +1196 5.48488 +1197 8.32916 +1198 5.44496 +1199 5.953 +1200 7.10064 +1201 4.28803 +1202 5.27418 +1203 3.79067 +1204 3.44724 +1205 4.17183 +1206 7.19842 +1207 4.32375 +1208 3.51299 +1209 7.615 +1210 5.69386 +1211 6.73423 +1212 4.51568 +1213 6.08616 +1214 5.21758 +1215 8.14411 +1216 4.06477 +1217 5.22976 +1218 5.07475 +1219 5.92439 +1220 4.9689 +1221 5.09276 +1222 7.43835 +1223 6.71407 +1224 7.02283 +1225 6.5295 +1226 4.40292 +1227 5.83422 +1228 3.70634 +1229 3.52758 +1230 6.0864 +1231 4.79487 +1232 5.2648 +1233 6.60461 +1234 4.95882 +1235 9.41937 +1236 5.13095 +1237 5.28013 +1238 5.44854 +1239 7.71878 +1240 5.56885 +1241 8.76006 +1242 4.56393 +1243 5.90289 +1244 6.17245 +1245 5.47762 +1246 6.85481 +1247 3.17205 +1248 4.86204 +1249 4.43452 +1250 6.97671 +1251 5.3337 +1252 5.43708 +1253 5.01141 +1254 7.23168 +1255 3.70348 +1256 4.66871 +1257 8.66635 +1258 7.63642 +1259 6.58896 +1260 5.63525 +1261 5.18847 +1262 4.60493 +1263 8.295 +1264 7.64526 +1265 3.59029 +1266 8.30829 +1267 5.61988 +1268 4.40627 +1269 8.59727 +1270 7.237 +1271 5.90024 +1272 4.03286 +1273 4.8429 +1274 7.10562 +1275 6.50655 +1276 4.64487 +1277 4.69878 +1278 7.97432 +1279 4.02501 +1280 5.38605 +1281 4.92341 +1282 5.07646 +1283 3.75685 +1284 5.31243 +1285 5.7707 +1286 5.68964 +1287 5.96062 +1288 7.85077 +1289 8.21576 +1290 6.68323 +1291 4.30884 +1292 4.784 +1293 5.21908 +1294 4.82005 +1295 4.40245 +1296 4.02024 +1297 3.62885 +1298 3.78701 +1299 3.55008 +1300 4.66264 +1301 5.58137 +1302 4.33701 +1303 4.93396 +1304 3.52374 +1305 7.13144 +1306 5.36387 +1307 8.97625 +1308 5.18498 +1309 9.05048 +1310 8.19838 +1311 4.42885 +1312 8.34232 +1313 3.94079 +1314 4.41342 +1315 7.69708 +1316 4.03687 +1317 4.88914 +1318 4.97387 +1319 5.60074 +1320 3.64249 +1321 3.99359 +1322 5.05358 +1323 7.22987 +1324 9.02307 +1325 3.92924 +1326 5.90228 +1327 6.68582 +1328 9.38571 +1329 4.23719 +1330 3.91918 +1331 6.00412 +1332 8.07751 +1333 4.80956 +1334 5.50254 +1335 9.28165 +1336 4.67539 +1337 4.8626 +1338 6.60907 +1339 6.82969 +1340 5.02785 +1341 4.99683 +1342 7.89183 +1343 9.24249 +1344 5.19206 +1345 4.25973 +1346 5.32035 +1347 4.13126 +1348 5.9532 +1349 6.48769 +1350 3.89076 +1351 5.66956 +1352 7.52047 +1353 5.81182 +1354 7.64656 +1355 5.39628 +1356 5.38481 +1357 4.57187 +1358 7.85941 +1359 3.19563 +1360 4.16723 +1361 7.58062 +1362 5.43379 +1363 4.5491 +1364 9.55822 +1365 5.41463 +1366 3.93709 +1367 5.58151 +1368 7.63004 +1369 7.19653 +1370 6.21067 +1371 4.16437 +1372 7.03794 +1373 6.03681 +1374 7.32543 +1375 8.75148 +1376 9.85852 +1377 5.51133 +1378 8.69481 +1379 5.56414 +1380 6.99819 +1381 3.55529 +1382 5.3928 +1383 4.84586 +1384 7.9864 +1385 6.53059 +1386 4.99042 +1387 4.16435 +1388 6.80177 +1389 5.45811 +1390 5.63078 +1391 3.96717 +1392 3.86136 +1393 3.20475 +1394 8.36851 +1395 5.32051 +1396 4.09927 +1397 4.30378 +1398 6.53894 +1399 9.57378 +1400 6.55006 +1401 6.34936 +1402 4.66909 +1403 4.92672 +1404 6.29711 +1405 6.13071 +1406 7.07983 +1407 3.38745 +1408 6.19644 +1409 3.70599 +1410 8.72514 +1411 5.01474 +1412 6.35499 +1413 8.51238 +1414 6.1006 +1415 8.31744 +1416 8.69373 +1417 5.3837 +1418 3.29415 +1419 3.17415 +1420 4.65337 +1421 3.77393 +1422 3.8875 +1423 7.11242 +1424 4.79596 +1425 4.074 +1426 4.91429 +1427 5.40041 +1428 4.50152 +1429 6.82147 +1430 7.03258 +1431 9.84567 +1432 5.28303 +1433 3.28496 +1434 5.3585 +1435 5.80604 +1436 6.24381 +1437 3.80452 +1438 8.7948 +1439 6.69635 +1440 5.38362 +1441 8.19043 +1442 6.65785 +1443 5.14952 +1444 8.66002 +1445 6.98012 +1446 5.82976 +1447 4.7057 +1448 4.19243 +1449 4.46766 +1450 4.94058 +1451 8.7967 +1452 5.51495 +1453 4.0043 +1454 5.16481 +1455 6.42095 +1456 6.01744 +1457 3.71544 +1458 5.73042 +1459 8.12425 +1460 3.95837 +1461 7.51813 +1462 9.24805 +1463 7.61923 +1464 4.43411 +1465 3.83737 +1466 3.95716 +1467 7.15998 +1468 5.65757 +1469 3.42947 +1470 7.66079 +1471 5.68317 +1472 4.17696 +1473 3.43991 +1474 4.08425 +1475 6.28225 +1476 5.03584 +1477 5.6927 +1478 4.82533 +1479 7.60644 +1480 3.80633 +1481 7.85466 +1482 4.0313 +1483 5.53088 +1484 4.79008 +1485 6.91984 +1486 7.05097 +1487 5.06758 +1488 5.28323 +1489 3.97634 +1490 7.07548 +1491 6.99741 +1492 5.39725 +1493 3.70965 +1494 5.20786 +1495 3.35697 +1496 8.30445 +1497 6.24412 +1498 5.02406 +1499 4.3192 +1500 3.75267 +1501 3.75419 +1502 6.70461 +1503 7.29339 +1504 7.25608 +1505 4.67025 +1506 7.00533 +1507 4.95845 +1508 5.9428 +1509 8.22798 +1510 6.09413 +1511 6.69181 +1512 4.68312 +1513 8.54909 +1514 9.17576 +1515 4.67904 +1516 5.70206 +1517 3.82361 +1518 4.83649 +1519 4.49647 +1520 6.62776 +1521 3.87563 +1522 3.82749 +1523 7.136 +1524 5.46372 +1525 7.49927 +1526 4.77056 +1527 6.99557 +1528 5.41681 +1529 5.67049 +1530 9.09783 +1531 6.2033 +1532 5.7676 +1533 6.10859 +1534 5.64874 +1535 4.25459 +1536 4.24224 +1537 7.54998 +1538 4.6898 +1539 3.65217 +1540 6.77849 +1541 7.38216 +1542 5.01269 +1543 9.63731 +1544 5.93312 +1545 6.67582 +1546 4.31103 +1547 7.11233 +1548 9.36116 +1549 5.26081 +1550 5.69302 +1551 3.48767 +1552 6.63839 +1553 6.58539 +1554 7.28664 +1555 3.81367 +1556 4.57632 +1557 5.76642 +1558 5.47675 +1559 4.10006 +1560 7.47012 +1561 4.71169 +1562 7.33109 +1563 3.61097 +1564 7.2049 +1565 5.17177 +1566 5.69784 +1567 5.66136 +1568 5.26364 +1569 5.80611 +1570 6.17947 +1571 7.04854 +1572 8.77365 +1573 4.85623 +1574 3.77604 +1575 4.3199 +1576 5.59875 +1577 7.20581 +1578 8.22279 +1579 6.75557 +1580 6.15071 +1581 8.40391 +1582 5.84813 +1583 6.71808 +1584 9.4805 +1585 5.78575 +1586 5.53995 +1587 6.22247 +1588 6.41044 +1589 4.20686 +1590 5.13741 +1591 9.43675 +1592 4.7142 +1593 3.98455 +1594 7.70331 +1595 5.7983 +1596 5.38736 +1597 6.27297 +1598 5.693 +1599 7.78512 +1600 9.5604 +1601 3.88507 +1602 5.01882 +1603 7.63484 +1604 5.06804 +1605 4.18197 +1606 4.43359 +1607 4.34535 +1608 4.02395 +1609 7.2371 +1610 8.47037 +1611 4.49746 +1612 8.23039 +1613 4.43065 +1614 4.82179 +1615 7.15842 +1616 4.60424 +1617 4.60142 +1618 4.98153 +1619 4.82699 +1620 6.48302 +1621 5.81494 +1622 9.77863 +1623 9.18164 +1624 8.97711 +1625 6.39388 +1626 4.3432 +1627 8.33951 +1628 5.09327 +1629 5.99447 +1630 4.3455 +1631 6.29698 +1632 3.33295 +1633 6.59657 +1634 6.95084 +1635 3.19532 +1636 5.517 +1637 5.79544 +1638 5.11606 +1639 5.09728 +1640 6.96594 +1641 4.43697 +1642 8.62959 +1643 6.33994 +1644 4.6679 +1645 6.9788 +1646 4.62802 +1647 9.58879 +1648 4.3363 +1649 5.16264 +1650 7.16104 +1651 5.92186 +1652 7.45343 +1653 3.24729 +1654 9.37208 +$EndElementData diff --git a/test/user/testdata/shark_22_ascii_missing_num_elements.msh b/test/user/testdata/shark_22_ascii_missing_num_elements.msh new file mode 100644 index 00000000..e01274de --- /dev/null +++ b/test/user/testdata/shark_22_ascii_missing_num_elements.msh @@ -0,0 +1,3978 @@ +$MeshFormat +2.2 0 8 +$EndMeshFormat +$Nodes +652 +1 -0.0733436 0.0816748 0.056402 +2 -0.0729126 0.0537921 0.00170478 +3 -0.072634 0.0799069 0.0578949 +4 -0.0715817 0.0520377 0.00292576 +5 -0.0701949 0.0802569 0.0450431 +6 -0.0687698 0.060971 0.00326551 +7 -0.06778 0.060358 0.00473741 +8 -0.0672796 0.0809249 0.0425553 +9 -0.0658074 0.0806443 0.0552302 +10 -0.064933 0.0788176 0.0453762 +11 -0.0636555 0.0610198 0.00141989 +12 -0.0636111 0.0566004 -0.000556663 +13 -0.0636791 0.0819076 0.0524468 +14 -0.0623445 0.0580268 0.00335683 +15 -0.0624856 0.0671058 0.00581638 +16 -0.0601398 0.0781111 0.0317589 +17 -0.0599443 0.0685632 0.00992449 +18 -0.0592787 0.0571239 0.00105116 +19 -0.0587906 0.0719999 0.0117948 +20 -0.0575605 0.0730663 0.016213 +21 -0.057624 0.0811803 0.0403639 +22 -0.0572339 0.0769387 0.0223219 +23 -0.0559974 0.0749629 0.0235691 +24 -0.0542321 0.0763209 0.0344665 +25 -0.0540672 0.0649483 0.00821813 +26 -0.0541685 0.0661135 0.00437935 +27 -0.0532966 0.0805356 0.0466758 +28 -0.0517252 0.0761185 0.0183218 +29 -0.0505257 0.068877 0.0152572 +30 -0.0503803 0.0772638 0.0406423 +31 -0.0472855 0.0641041 0.00381053 +32 -0.0469016 0.0648796 0.00821733 +33 -0.0474599 0.0727268 0.0265623 +34 -0.0464733 0.070912 0.0103373 +35 -0.0444756 0.0755674 0.0221683 +36 -0.0440208 0.0774313 0.0371107 +37 -0.0434135 0.0685101 0.0213943 +38 -0.0425401 0.0668787 0.0159114 +39 -0.0405353 0.0730163 0.0309862 +40 -0.0386417 0.073548 0.0160682 +41 -0.037401 0.0664899 0.0122191 +42 -0.0358693 0.0689445 0.0243885 +43 -0.0351058 0.0687771 0.0124837 +44 -0.0333614 0.071165 0.0238503 +45 -0.0325564 0.0696271 0.024504 +46 -0.032455 0.0625178 0.0200737 +47 -0.0305469 0.0729973 0.0173921 +48 -0.0276941 0.0652386 0.0128238 +49 -0.0272717 0.0628782 0.0141328 +50 -0.0263428 0.00735496 0.00505748 +51 -0.0256055 0.00658056 0.00327552 +52 -0.0252856 0.0610141 0.0227762 +53 -0.0250237 -0.00678856 0.00359213 +54 -0.0242889 -0.00589458 0.00589675 +55 -0.0216872 0.0639735 0.0255561 +56 -0.0215721 -0.0119744 0.00619585 +57 -0.0195136 0.0542304 0.0216195 +58 -0.0168343 0.0649534 0.0236547 +59 -0.0161373 -0.00420129 0.00881529 +60 -0.0148726 0.0585475 0.0106707 +61 -0.0140647 0.0517836 0.0159197 +62 -0.0142986 0.0543801 0.0051496 +63 -0.0139611 -0.0178642 0.00651265 +64 -0.0139803 0.0554055 0.0115694 +65 -0.0124373 0.0606817 0.0122622 +66 -0.0127423 0.0580719 0.0285553 +67 -0.0127412 -0.0704232 0.0234664 +68 -0.0126173 -0.0801905 0.022154 +69 -0.0125269 0.0592002 0.0346418 +70 -0.0122498 -0.080596 0.0191154 +71 -0.0121442 -0.0691943 0.0191352 +72 -0.0123618 0.0658492 0.0197519 +73 -0.0121018 -0.063334 0.0245151 +74 -0.0118539 0.0462485 0.0243954 +75 -0.0111067 0.0637388 0.0161162 +76 -0.0110042 -0.0624802 0.0276395 +77 -0.0109072 0.046219 0.0183571 +78 -0.0107037 -0.000325242 0.00950432 +79 -0.010183 -0.0121386 0.00674337 +80 -0.00977442 -0.0638147 0.0162637 +81 -0.0097669 -0.0699334 0.0156591 +82 -0.00942656 -0.0836042 0.0182705 +83 -0.009321 -0.0852334 0.0216727 +84 -0.00803502 0.0401179 0.0263407 +85 -0.00857808 -0.0579335 0.0163943 +86 -0.00793158 -0.0190616 0.0121625 +87 -0.00782675 0.0573514 0.028038 +88 -0.00773028 -0.0620746 0.0302044 +89 -0.00764665 0.0537773 0.00961295 +90 -0.00721562 -0.0507362 0.0224357 +91 -0.00717408 -0.0528249 0.0179333 +92 -0.00651588 -0.00739691 0.013024 +93 -0.00691116 -0.00014073 0.00823716 +94 -0.00661131 0.044183 0.0123 +95 -0.00658663 0.0535365 0.0326225 +96 -0.00630954 -0.0850657 0.0194796 +97 -0.00616497 -0.0797841 0.0261073 +98 -0.00582999 -0.0494502 0.0287705 +99 -0.00563359 0.0476479 0.00934546 +100 -0.00506609 -0.0425596 0.0250833 +101 -0.00453974 -0.0405694 0.0173853 +102 -0.00447266 0.0319291 0.0205877 +103 -0.00434886 0.0267225 0.00648417 +104 -0.00418386 0.0253438 0.00842196 +105 -0.0041733 -0.0606038 0.0122716 +106 -0.00385183 0.0479538 0.00869149 +107 -0.00333705 0.051389 0.031593 +108 -0.00333565 -0.0693881 0.0119551 +109 -0.00333748 -0.0650683 0.0110291 +110 -0.00292457 0.0475597 0.0319288 +111 -0.00280471 -0.0353375 0.0238411 +112 -0.00273019 -0.0493159 0.0135756 +113 -0.00255346 -0.0452657 0.0126112 +114 -0.00249178 -0.0598565 0.010934 +115 -0.00247351 -0.0533955 0.0149632 +116 -0.00280465 0.0288144 0.0300227 +117 -0.00225175 -0.030519 0.0236922 +118 -0.00205777 -0.0595101 0.00715068 +119 -0.0018581 -0.0627033 0.0116048 +120 -0.00150112 -0.0384203 0.0313885 +121 -0.00143547 -0.0337232 0.0176227 +122 -0.00136747 -0.062725 0.0150152 +123 -0.000884775 -0.0587825 0.0143119 +124 -0.000624659 -0.0247814 0.0257906 +125 -0.000489974 0.0225414 0.0188523 +126 -6.05566e-05 0.0171338 0.0234086 +127 0.00150381 0.0360475 0.00675461 +128 0.000282178 -0.0241462 0.0174969 +129 0.000347869 -0.0675237 0.0324883 +130 0.000429839 -0.0422219 0.0349169 +131 0.00028168 -0.0273698 0.0312235 +132 0.000952705 -0.0267391 0.0143612 +133 0.00105244 0.0186951 0.00689988 +134 0.0011109 -0.0779453 0.014663 +135 0.00137887 0.00842564 0.0258445 +136 0.00107238 -0.0462225 0.00980545 +137 0.00158113 -0.0561697 0.005809 +138 0.00165921 -0.0142314 0.0114909 +139 0.00169065 -0.00330978 0.027848 +140 0.0017282 0.0264299 0.00972258 +141 0.00196109 -0.062067 0.0125082 +142 0.00198494 -0.0249792 0.0122768 +143 0.00206797 -0.0322322 0.0125632 +144 0.00219287 -0.00991015 0.0199027 +145 0.00223228 -0.065619 0.00972103 +146 0.00226787 -0.06664 0.0139131 +147 0.00233081 0.00970751 0.0349608 +148 0.0023033 -0.0550711 0.0357611 +149 0.00284591 -0.0695874 0.0109337 +150 0.00313658 0.0123831 0.0152878 +151 0.00325266 -0.000639164 0.0164744 +152 0.00354678 -0.0651674 0.00553443 +153 0.00434877 0.0392681 0.00656793 +154 0.0034004 -0.0624097 0.0143354 +155 0.00410027 0.052311 0.0146156 +156 0.00425687 -0.0110681 0.0377954 +157 0.0043501 -0.0020508 0.015115 +158 0.00444422 -0.0785667 0.0168482 +159 0.00471578 -0.00872746 0.0133588 +160 0.00486541 0.0192794 0.0102326 +161 0.00475235 0.0259901 0.00777948 +162 0.00497525 -0.0797755 0.0244877 +163 0.0052286 0.0545416 0.0234287 +164 0.00513856 -0.0361953 0.00904286 +165 0.00543656 -0.016404 0.0117933 +166 0.00521097 0.0361763 0.0357574 +167 0.00563068 0.0458779 0.0101474 +168 0.00602624 -0.0598053 0.00448538 +169 0.00669265 -0.0730234 0.0300997 +170 0.00671975 -0.0647944 0.0149968 +171 0.00743572 0.0219428 0.00498754 +172 0.00806977 -0.0676622 0.0106835 +173 0.00858002 0.0185363 0.00804532 +174 0.00900922 -0.0527441 0.0382868 +175 0.00967438 -0.0310472 0.0412759 +176 0.00969027 -0.0470756 0.00574739 +177 0.00982547 -0.0777201 0.0238208 +178 0.010337 -0.0646559 0.00738197 +179 0.0103691 -0.0715108 0.0301524 +180 0.0108524 -0.0651923 0.0107074 +181 0.0112352 0.0223598 0.00496048 +182 0.0115762 0.0360388 0.034027 +183 0.011811 0.0150563 0.0411225 +184 0.0119389 -0.0710873 0.0142927 +185 0.011481 0.000850754 0.00890493 +186 0.0122581 0.0177891 0.00726338 +187 0.0126044 0.0285097 0.0071727 +188 0.0126077 -0.0410848 0.00487059 +189 0.01325 0.0245576 0.00385279 +190 0.0133342 -0.0301914 0.00695184 +191 0.0134526 -0.00467313 0.044297 +192 0.0140263 0.0415073 0.0128325 +193 0.0139319 -0.0627506 0.0126489 +194 0.0144402 0.0213321 0.0408733 +195 0.0145153 -0.0120242 0.00709154 +196 0.0145254 0.0314471 0.00762861 +197 0.0143606 -0.0539791 0.00638859 +198 0.0153705 -0.0588177 0.00913193 +199 0.0158483 0.0424843 0.0267153 +200 0.0161677 0.0082135 0.0752128 +201 0.0160709 -0.0693691 0.0267104 +202 0.0163112 0.021127 0.00658374 +203 0.0163956 0.0418119 0.0180916 +204 0.0166653 0.00513625 0.0449469 +205 0.0171438 -0.00939438 0.0462661 +206 0.0174416 -0.0497054 0.0373642 +207 0.0174198 -0.0656937 0.0159871 +208 0.0177387 0.0346114 0.0053358 +209 0.0178439 0.0247259 0.00729322 +210 0.018247 0.0346901 0.00258831 +211 0.0182074 -0.0318958 0.0424624 +212 0.0183988 -0.00142899 0.0496692 +213 0.0188182 -0.018825 0.0447569 +214 0.0188285 0.0147456 0.0461032 +215 0.0188626 0.015416 0.041072 +216 0.0190811 -0.00419709 0.0686858 +217 0.0195945 0.0084326 0.064095 +218 0.0197498 -0.00217441 0.0583864 +219 0.0198208 0.00539755 0.0587622 +220 0.0200137 0.0324539 0.00354185 +221 0.020151 -0.0145671 0.0500049 +222 0.0203386 -0.00326709 0.0702447 +223 0.0209148 0.00523036 0.0681576 +224 0.0208447 0.0121045 0.0546374 +225 0.0209724 0.00970633 0.0633876 +226 0.020604 -0.0121123 0.00591309 +227 0.0212498 -0.0289526 0.00565549 +228 0.0216078 -0.0380775 0.00479088 +229 0.0216875 -0.00997672 0.0619769 +230 0.0220658 0.00705093 0.0456869 +231 0.0223002 -0.0558455 0.0110476 +232 0.0223137 -0.0154618 0.0494217 +233 0.0229336 0.00417573 0.0589573 +234 0.0231427 0.0278288 0.0125965 +235 0.0231751 0.027241 0.0309726 +236 0.0233259 0.0160686 0.00756079 +237 0.0234095 0.0318943 0.0199392 +238 0.0234462 -0.00393483 0.0583985 +239 0.0235915 -0.0597066 0.0170609 +240 0.0240196 -0.0108777 0.0466362 +241 0.024123 -0.00330273 0.0464733 +242 0.0242099 -0.0321428 0.0398591 +243 0.0244244 0.00347947 0.0416421 +244 0.024564 -0.0175604 0.0433407 +245 0.0253979 -0.0453083 0.0344803 +246 0.0256103 0.0267734 0.0284514 +247 0.0259312 -0.0445208 0.00878379 +248 0.025959 -0.0133125 0.00624018 +249 0.0265967 -0.0369666 0.00635268 +250 0.0273245 -0.0066598 0.0412078 +251 0.0277597 -0.0467651 0.0304517 +252 0.0275944 -0.0515878 0.0207552 +253 0.0282687 0.0208205 0.0174814 +254 0.0290859 0.0112094 0.012597 +255 0.0293048 -0.0474855 0.0256026 +256 0.0296506 -0.0466043 0.0156453 +257 0.0304236 0.0134394 0.031696 +258 0.0304518 -0.0291908 0.00746031 +259 0.03126 -0.044124 0.016095 +260 0.0321715 -0.043346 0.0242104 +261 0.0322352 -0.0402733 0.0141242 +262 0.0323149 0.01052 0.0200521 +263 0.0324768 -0.0397188 0.0271188 +264 0.0325431 -0.0291932 0.0340382 +265 0.0332479 -0.0329826 0.0117351 +266 0.0338676 -0.0346121 0.0252676 +267 0.0341522 -0.00293196 0.033596 +268 0.0341882 -0.0361716 0.0179088 +269 0.0344969 -0.0256263 0.0309923 +270 0.0345138 -0.00958586 0.0123416 +271 0.0348872 -0.0128566 0.0339912 +272 0.0349524 -0.0273994 0.0177976 +273 0.0349556 -0.000677158 0.0209767 +274 0.0350004 -0.028049 0.00876142 +275 0.0353194 -0.0100316 0.0154749 +276 0.0354214 -0.0195455 0.0173172 +277 0.0355775 -0.0309821 0.0107592 +278 0.0360305 -0.0150581 0.0232372 +279 0.0363938 -0.0285041 0.0132933 +280 0.0374738 -0.00607371 0.0123945 +281 0.041317 -0.0210454 0.0131228 +282 0.0425886 -0.0120136 0.0129537 +283 0.0475164 -0.00753527 0.00853843 +284 0.0492593 -0.00704914 0.00938067 +285 0.0496752 -0.0170405 0.0106038 +286 0.0498676 -0.0259318 0.00619626 +287 0.052402 -0.022331 0.00866719 +288 0.0516897 -0.011391 0.0103437 +289 0.0559595 -0.0106346 0.00698866 +290 0.0596531 -0.0214295 0.0059579 +291 0.066312 -0.0158462 0.00759335 +292 0.0672852 -0.00331292 0.00667068 +293 0.0687074 -0.0027598 0.00829441 +294 0.0687083 -0.0084515 0.00881385 +295 0.0702857 -0.00694567 0.00665748 +296 0.02471 0.00101921 0.00688758 +297 0.00641783 -0.0341512 0.0233596 +298 0.024018 0.00854392 0.00722419 +299 0.0251696 0.00942127 0.00784613 +300 -0.019815 0.0686939 0.0189821 +301 0.0416697 -0.017118 0.00864259 +302 -0.00440288 -0.0698432 0.0205811 +303 -0.0033606 0.0600219 0.0217676 +304 0.0268544 0.00322876 0.0080825 +305 0.00855449 0.0107052 0.00928038 +306 0.0219179 0.00585482 0.0121236 +307 0.0199208 0.0175811 0.0336776 +308 0.0210521 -0.0362113 0.0256186 +309 0.0339797 -0.00194129 0.0163861 +310 0.03202 0.000337126 0.0126992 +311 0.0119633 0.0163586 0.0147908 +312 0.0248778 0.0056119 0.0321775 +313 0.00892971 -0.0563678 0.0287948 +314 0.0174837 0.027107 0.0210333 +315 -0.0170518 0.00346089 0.00554363 +316 0.0144974 -0.0120686 0.0314959 +317 0.00336155 -0.00103205 0.0364574 +318 0.00707711 -0.0204903 0.0185209 +319 0.010517 -0.00309481 0.0232445 +320 -0.00559352 0.0373259 0.0172753 +321 -0.00523735 -0.0230725 0.0111224 +322 0.0151072 -0.0538804 0.0213778 +323 0.0347571 -0.0188174 0.0105515 +324 0.0278657 -0.0183642 0.0156758 +325 -0.00338013 -0.0543805 0.0329679 +326 -0.0196332 0.0593213 0.0251138 +327 0.0648163 -0.0143432 0.00627944 +328 -0.00336175 -0.0187472 0.00979996 +329 -0.0059938 -0.0214388 0.00941436 +330 0.0204933 0.0262773 0.00994486 +331 0.0153554 0.00838654 0.0105168 +332 -0.064082 0.064994 0.00682263 +333 -0.0406296 0.0703091 0.0249838 +334 -0.0197677 0.0563929 0.0156108 +335 -0.0506931 0.0781816 0.0304629 +336 0.0171972 -0.00100568 0.011485 +337 0.0314619 -0.0225976 0.00774901 +338 -0.00980694 0.0515267 0.0104574 +339 -0.00435185 0.0493969 0.0137744 +340 0.0449063 -0.0117353 0.00859937 +341 0.00159087 -0.0450385 0.027858 +342 -0.00469537 -0.0637251 0.0233918 +343 0.0424219 -0.0285632 0.00857374 +344 0.0603894 -0.00835109 0.00935053 +345 -0.0147113 -0.0156046 0.00918376 +346 -0.0528157 0.0611754 0.00480955 +347 -0.0173765 -0.00887149 0.00520522 +348 0.0108104 0.02268 0.0130558 +349 -0.00899905 -0.0208443 0.00915416 +350 -0.0449914 0.0768094 0.0302276 +351 -0.0408502 0.06658 0.00836849 +352 -0.0199988 -0.0118916 0.004906 +353 0.00337131 0.0455887 0.0238561 +354 0.00477413 -0.0721541 0.0211645 +355 -0.00344193 -0.049333 0.032475 +356 0.0427245 -0.0268877 0.00738607 +357 0.0272704 -0.0238375 0.00669928 +358 -0.00610544 -0.0476638 0.0181008 +359 -0.00760153 0.0503529 0.00747858 +360 0.0131109 -0.0422224 0.0405109 +361 0.00214561 -0.0490294 0.0151357 +362 -0.0598224 0.0805424 0.0511855 +363 -0.0204542 0.0588165 0.013102 +364 0.059357 -0.0190886 0.00813027 +365 -0.00100716 0.0422264 0.0325724 +366 0.0325535 -0.0244764 0.012522 +367 -0.000431427 -0.0574818 0.0137747 +368 0.0114251 0.0275734 0.00440942 +369 0.00337666 -0.0559724 0.0148659 +370 -0.0262911 0.0586227 0.0207785 +371 -0.0699467 0.0813567 0.0499003 +372 0.0494602 -0.0133111 0.00757754 +373 0.00758285 0.0333008 0.0104911 +374 0.00657287 0.032122 0.00603963 +375 0.000332803 -0.0511328 0.0180756 +376 -0.021764 0.0620607 0.0118108 +377 -0.0454672 0.075167 0.035911 +378 0.00139884 0.045926 0.0128133 +379 0.0176314 0.0311493 0.00370344 +380 -0.0159418 -0.0158578 0.00793814 +381 -0.0229387 0.0691641 0.0166572 +382 -0.00133409 -0.0449329 0.0187829 +383 -0.0538019 0.0611146 0.00198764 +384 0.0305208 -0.00256491 0.0101919 +385 0.0623596 -0.00697151 0.00683979 +386 0.0236819 -0.00777996 0.0526871 +387 0.0118138 -0.0144241 0.0430193 +388 0.0137156 -0.00365078 0.00732253 +389 -0.0257884 0.0686739 0.0150694 +390 -0.0530331 0.060812 0.00248197 +391 -0.000421194 -0.0523335 0.00879177 +392 0.0193846 -0.00072024 0.0649221 +393 0.00485856 0.0133946 0.0114741 +394 -0.0053823 -0.0743714 0.0141262 +395 0.016958 0.0166471 0.00740593 +396 0.0429338 -0.0266961 0.0110582 +397 -0.0650475 0.05473 0.00191127 +398 0.00924818 0.0356698 0.00715588 +399 -0.042468 0.0652669 0.00790867 +400 0.00699205 0.0348997 0.00576165 +401 -0.012123 0.00171435 0.00688121 +402 0.017741 0.00126373 0.0717161 +403 -0.00477874 -0.0228765 0.0123522 +404 -0.05496 0.0793832 0.0329037 +405 -0.0253736 -0.000654191 0.00342534 +406 0.0220159 -0.0128389 0.0555838 +407 0.0187915 0.00366305 0.0653901 +408 -0.0635923 0.0794618 0.0351284 +409 0.0187293 0.00901455 0.0689246 +410 -0.0507436 0.0790633 0.0364811 +411 0.00440962 0.0291856 0.00589534 +412 -0.0610541 0.0815764 0.0467801 +413 -0.0264169 0.0641898 0.0180225 +414 0.0590681 -0.0129818 0.00969293 +415 0.0316732 -0.013669 0.00892731 +416 -0.0368828 0.0732351 0.028231 +417 0.0147007 -0.0293577 0.0425282 +418 -0.00226105 0.042112 0.00818422 +419 -0.022404 0.068624 0.0211714 +420 0.018834 0.0296379 0.0101126 +421 0.0545664 -0.023882 0.00596013 +422 -0.0610274 0.0626039 0.00623226 +423 0.0209345 -0.0123916 0.0558755 +424 -0.064258 0.0639612 0.00701622 +425 -0.0530259 0.0709966 0.0104874 +426 -0.000350232 0.0328643 0.00950357 +427 0.0179821 0.0260225 0.00525665 +428 -0.071629 0.0809096 0.0500374 +429 0.0431333 -0.00662611 0.0109755 +430 -0.0367738 0.072104 0.0272887 +431 -0.00147996 0.0424733 0.00778004 +432 -0.0489442 0.0792518 0.0424775 +433 0.0178184 0.00830923 0.0698262 +434 -0.00256208 -0.0518644 0.0119693 +435 -0.0024457 0.0347988 0.0115191 +436 -0.0226391 0.067054 0.0236986 +437 -0.0250562 0.070839 0.0181046 +438 0.0157661 -0.010775 0.0444953 +439 -0.0587069 0.0610686 0.00549325 +440 -0.0561989 0.0607157 0.00436391 +441 0.0028322 0.0311045 0.0076099 +442 -0.061857 0.079748 0.0514834 +443 -0.0580072 0.0744854 0.0170926 +444 0.017366 0.0281829 0.00449304 +445 0.0175246 0.0303053 0.00632184 +446 -0.0583716 0.0812348 0.0494755 +447 -0.0627638 0.0811059 0.0418948 +448 0.00958337 0.0391723 0.00889538 +449 0.0164997 0.0327763 0.00400793 +450 -0.0100537 -0.019407 0.0104569 +451 0.0535082 -0.023589 0.00757618 +452 -0.0184567 0.0672393 0.0165986 +453 -0.0660887 0.0639515 0.00557639 +454 -0.0085005 0.0591911 0.0132991 +455 0.0527123 -0.00658592 0.00801901 +456 0.00664445 0.0147496 0.00979726 +457 -0.0323364 0.0646841 0.013176 +458 -0.0684981 0.0817682 0.0541475 +459 0.0424951 -0.00680449 0.0104665 +460 -0.01583 0.0638299 0.0140017 +461 -0.0408586 0.0747808 0.0276312 +462 -0.0213675 0.00505684 0.00440033 +463 -0.0609542 0.0784149 0.029815 +464 0.0458286 -0.0196104 0.0115924 +465 0.0619857 -0.0044448 0.00717137 +466 -0.0549453 0.0736446 0.0144159 +467 -0.0660739 0.0797747 0.0511232 +468 -0.0150243 -0.0138696 0.00597473 +469 -0.0208919 0.0664273 0.014553 +470 -0.0583912 0.0766731 0.0277458 +471 -0.00499489 -0.0492059 0.0154875 +472 -0.0177596 -0.0149926 0.00640227 +473 -0.0656257 0.0638276 0.00437301 +474 -0.00111824 -0.0505712 0.010634 +475 -0.0234714 0.0595273 0.0150887 +476 -0.0117477 -0.00786715 0.0107629 +477 -0.0329423 0.0662408 0.012525 +478 -0.0588644 0.0778049 0.0265316 +479 -0.038272 0.0710121 0.0277124 +480 0.0147178 0.0228905 0.00513556 +481 -0.00242697 -0.0228032 0.0106496 +482 -0.00998317 -0.0196685 0.00798312 +483 0.00194711 0.0338412 0.00734265 +484 -0.0101071 0.0571173 0.0108272 +485 -0.000192036 0.0305177 0.010316 +486 -0.0662236 0.0609953 0.00234663 +487 -0.0383437 0.071981 0.0290737 +488 0.0464353 -0.0271448 0.00729223 +489 -0.0113654 0.0558876 0.00985606 +490 -0.0600686 0.0581853 0.00037707 +491 0.0184892 0.00651809 0.072001 +492 -0.0272353 0.0661385 0.0125002 +493 0.0386787 -0.00939756 0.0110365 +494 -0.00702298 -0.0554164 0.0301677 +495 -0.0387296 0.0725599 0.0291973 +496 -0.0195884 -0.00971304 0.00731553 +497 0.000980398 0.0340005 0.00831153 +498 -0.00251349 -0.0493306 0.0137872 +499 -0.0208118 0.00468072 0.00662791 +500 0.0145465 0.0247675 0.00685396 +501 0.0539643 -0.00601143 0.00911787 +502 0.0615879 -0.00432066 0.00875869 +503 -0.0649217 0.0800024 0.0383643 +504 0.00460493 0.00849738 0.0127005 +505 -0.0606311 0.0803611 0.0379233 +506 -0.00316884 0.0400824 0.00969248 +507 -0.0308482 0.067467 0.0126012 +508 0.0120049 0.00511369 0.00824306 +509 0.0117314 0.0134932 0.00784586 +510 0.0067401 0.0222359 0.00786688 +511 0.000365941 0.0444987 0.0334101 +512 0.00589042 0.0427357 0.0325284 +513 0.0134556 0.013691 0.0071386 +514 0.0155774 0.00572549 0.00675779 +515 -0.0442054 0.0654197 0.00607699 +516 0.00863004 0.0184766 0.00878081 +517 -0.0111016 -0.0170398 0.0107756 +518 -0.0162643 0.06208 0.0123266 +519 -0.0670643 0.0628756 0.0047451 +520 -0.0673064 0.0791769 0.0489333 +521 -0.0566743 0.0588231 0.00264455 +522 -0.0713841 0.080001 0.0523997 +523 -0.0690781 0.0794039 0.0521145 +524 -0.0589744 0.0702988 0.0123753 +525 -0.0108026 0.05228 0.00636676 +526 -0.0113486 0.0541547 0.00728553 +527 -0.0299136 0.0686241 0.0165753 +528 0.0505332 -0.0225927 0.00635398 +529 0.0180077 0.0031318 0.0704387 +530 -0.0235313 0.0640143 0.012641 +531 -0.0235569 0.00584404 0.00381922 +532 0.0384718 -0.0113423 0.0144484 +533 0.0182407 0.00232532 0.0728388 +534 -0.0235752 0.00407866 0.00373027 +535 -0.011585 0.0522432 0.00647843 +536 0.0400312 -0.00904366 0.0126741 +537 -0.0178591 -0.000359808 0.00797485 +538 -0.067167 0.0625514 0.00392853 +539 -0.0596438 0.0779391 0.0290601 +540 0.0013543 0.0302152 0.00901705 +541 0.0168301 0.00522322 0.0737244 +542 0.0174324 0.00448014 0.0738384 +543 -0.0618546 0.0649931 0.00590465 +544 0.0194429 0.0304209 0.00452872 +545 -0.0236633 0.0648084 0.0124456 +546 -0.00249493 -0.0562542 0.012985 +547 -0.0025263 -0.0246783 0.0125409 +548 -0.0396392 0.0718092 0.02876 +549 -0.0158083 -0.0164708 0.00645267 +550 0.016879 0.0245859 0.0055459 +551 -0.0688499 0.0811361 0.0461884 +552 0.0290982 -0.00647478 0.00827907 +553 -0.041817 0.0761358 0.0343691 +554 -0.0642688 0.0653922 0.00517065 +555 -0.0162175 0.00239503 0.00694561 +556 0.00467524 0.0360758 0.00643588 +557 -0.0222973 0.0035638 0.00646752 +558 -0.0708092 0.0801688 0.0482801 +559 -0.0549524 0.0787083 0.0296023 +560 -0.0631054 0.0672415 0.00811831 +561 -0.0155444 -0.0163359 0.0060847 +562 -0.0574097 0.0788047 0.0473507 +563 -0.0558952 0.0591814 0.001764 +564 -0.0177409 0.0619627 0.0144786 +565 -0.00178349 -0.0487397 0.0125937 +566 -0.0111058 0.0522074 0.00829904 +567 -0.0260139 0.00360897 0.00461987 +568 -0.0204566 0.00423454 0.00564674 +569 0.00612936 0.0370467 0.00680554 +570 0.010446 0.0313554 0.00705031 +571 -0.0569353 0.05965 0.00118235 +572 -0.0506685 0.0625792 0.00279292 +573 -0.0249761 0.00485573 0.00443819 +574 0.0172421 0.00725128 0.0738262 +575 -0.0219613 0.0643004 0.0138184 +576 -0.00260185 -0.0513557 0.0142694 +577 -0.0167422 0.00259292 0.00779623 +578 0.00214524 0.0341103 0.00650831 +579 -0.0236765 0.00572293 0.004305 +580 -0.0616879 0.0784644 0.0353636 +581 -0.0125522 0.0533024 0.00573952 +582 -0.00373263 -0.048886 0.014509 +583 -0.00253347 -0.0472982 0.0131992 +584 -0.0128746 -0.017623 0.00940414 +585 -5.43548e-05 0.0393803 0.00728201 +586 -0.0258702 0.00405717 0.00525282 +587 0.0183599 0.0265636 0.00640112 +588 0.0459896 -0.0257989 0.0100883 +589 -0.0295424 0.0680594 0.0247957 +590 -0.0245383 0.0634107 0.0123732 +591 0.0066096 0.0377811 0.00691952 +592 -0.0450015 0.0646553 0.00575343 +593 -0.0622505 0.0661482 0.00839783 +594 -0.0256248 0.0608105 0.0161665 +595 0.017488 0.00853314 0.0720965 +596 -0.0596734 0.0705097 0.00992485 +597 -0.0665798 0.0628689 0.00493615 +598 -0.0624322 0.0664941 0.0080812 +599 0.0436037 -0.00911409 0.00950451 +600 -0.0258241 0.00183578 0.00455937 +601 -0.0702703 0.0796913 0.0546337 +602 -0.027947 0.0630495 0.0231884 +603 -0.0601839 0.0704633 0.0106076 +604 -0.019796 -0.0130118 0.0069497 +605 -0.0183149 0.0630548 0.012418 +606 -0.0302535 0.0701272 0.02364 +607 -0.0574291 0.0790851 0.0314511 +608 -0.0506885 0.0650762 0.00396145 +609 -0.021101 0.0616869 0.0137094 +610 -0.0331684 0.0670427 0.023997 +611 0.0134393 0.00644533 0.00718965 +612 -0.0111807 -0.0194906 0.00818236 +613 -0.0255718 0.00304117 0.00332801 +614 -0.0126697 -0.015488 0.00653208 +615 -0.0247074 0.00660999 0.00551935 +616 0.0173416 0.0031807 0.0727906 +617 0.0172416 0.0236783 0.00588169 +618 0.0190309 0.0293428 0.00437137 +619 0.016715 0.00646681 0.0747173 +620 -0.0362286 0.072292 0.023504 +621 -0.0193589 -0.00042516 0.00470745 +622 -0.0218861 0.0643631 0.0125137 +623 -0.0102557 0.0512168 0.00711881 +624 0.0404202 -0.00631757 0.0116411 +625 0.0462272 -0.00679819 0.0101561 +626 -0.0259792 0.0656558 0.0150971 +627 0.0162732 0.0229634 0.00624384 +628 0.00353474 0.0364474 0.00843339 +629 4.6368e-06 0.0388726 0.00973083 +630 -0.0216501 0.0633078 0.012475 +631 -0.0653553 0.0635995 0.0060088 +632 -0.0129397 0.0533345 0.00604151 +633 -0.00189413 -0.0244631 0.013557 +634 -0.0610974 0.0673557 0.00916116 +635 0.0169636 0.00823874 0.0726305 +636 -0.0262169 0.00566462 0.00486021 +637 -0.00105663 -0.050339 0.013034 +638 -0.0522352 0.0618469 0.00239028 +639 -0.0658611 0.0623674 0.00600767 +640 -0.0308719 0.0671807 0.0240148 +641 -0.0271033 0.0631674 0.0232081 +642 0.000463176 0.0377435 0.00713404 +643 0.0197653 -0.0105149 0.0573133 +644 -0.0261272 0.00574879 0.00514751 +645 -0.0256133 0.00236555 0.00535812 +646 0.0395658 -0.00664927 0.0115095 +647 -0.0346515 0.0704144 0.0260764 +648 -0.0676857 0.0619198 0.00410476 +649 -0.0352382 0.0722683 0.0261851 +650 -0.0489272 0.0632235 0.00329626 +651 -0.0514659 0.0617489 0.00295197 +652 -0.070483 0.0805389 0.0464472 +$EndNodes +$Elements +1 4 0 26 15 543 25 +2 4 0 227 308 190 188 +3 4 0 203 353 199 163 +4 4 0 331 305 504 150 +5 4 0 142 328 128 138 +6 4 0 490 439 18 571 +7 4 0 364 289 287 414 +8 4 0 296 336 304 298 +9 4 0 564 419 300 381 +10 4 0 398 569 373 591 +11 4 0 486 473 639 422 +12 4 0 338 89 566 489 +13 4 0 332 554 543 424 +14 4 0 80 67 71 302 +15 4 0 149 146 109 108 +16 4 0 98 90 375 342 +17 4 0 341 308 325 313 +18 4 0 147 314 126 116 +19 4 0 124 318 156 131 +20 4 0 245 322 206 308 +21 4 0 348 311 516 186 +22 4 0 135 150 319 151 +23 4 0 147 314 307 311 +24 4 0 464 588 301 528 +25 4 0 461 33 35 333 +26 4 0 196 192 373 314 +27 4 0 108 81 302 122 +28 4 0 366 258 227 357 +29 4 0 511 107 512 353 +30 4 0 146 170 354 172 +31 4 0 297 175 156 130 +32 4 0 130 297 175 308 +33 4 0 318 159 319 195 +34 4 0 154 123 122 342 +35 4 0 261 308 259 260 +36 4 0 132 142 128 318 +37 4 0 241 250 240 205 +38 4 0 226 227 248 324 +39 4 0 575 609 475 49 +40 4 0 375 91 123 90 +41 4 0 260 308 255 251 +42 4 0 517 612 63 482 +43 4 0 120 117 131 297 +44 4 0 318 131 297 156 +45 4 0 147 319 311 307 +46 4 0 131 120 297 130 +47 4 0 120 297 111 117 +48 4 0 308 174 206 360 +49 4 0 148 313 325 175 +50 4 0 148 313 175 174 +51 4 0 302 80 122 81 +52 4 0 107 353 511 110 +53 4 0 322 231 198 197 +54 4 0 61 58 564 57 +55 4 0 240 386 212 221 +56 4 0 121 297 143 117 +57 4 0 121 297 117 111 +58 4 0 307 235 314 182 +59 4 0 307 314 166 182 +60 4 0 417 308 175 316 +61 4 0 308 175 360 417 +62 4 0 601 9 458 1 +63 4 0 459 429 536 599 +64 4 0 211 242 206 308 +65 4 0 528 588 301 356 +66 4 0 316 297 308 175 +67 4 0 197 188 308 228 +68 4 0 231 308 228 197 +69 4 0 231 197 322 308 +70 4 0 188 197 308 361 +71 4 0 322 361 308 197 +72 4 0 259 308 256 255 +73 4 0 298 306 304 299 +74 4 0 302 342 146 122 +75 4 0 251 322 245 308 +76 4 0 298 306 299 236 +77 4 0 342 302 169 129 +78 4 0 157 319 331 150 +79 4 0 190 195 324 227 +80 4 0 146 342 354 154 +81 4 0 190 297 308 324 +82 4 0 236 254 306 299 +83 4 0 354 179 201 322 +84 4 0 308 297 188 361 +85 4 0 361 188 164 297 +86 4 0 195 165 190 318 +87 4 0 307 215 257 235 +88 4 0 194 235 215 307 +89 4 0 174 129 148 313 +90 4 0 169 313 129 174 +91 4 0 322 255 251 201 +92 4 0 366 265 308 258 +93 4 0 227 308 258 366 +94 4 0 258 308 249 265 +95 4 0 227 308 228 258 +96 4 0 448 192 373 196 +97 4 0 228 308 249 258 +98 4 0 296 298 514 336 +99 4 0 125 150 348 126 +100 4 0 125 160 348 150 +101 4 0 244 264 242 316 +102 4 0 264 316 244 271 +103 4 0 224 233 225 219 +104 4 0 107 353 163 199 +105 4 0 217 223 219 225 +106 4 0 308 174 313 206 +107 4 0 206 313 179 174 +108 4 0 241 230 212 233 +109 4 0 241 233 212 218 +110 4 0 267 278 312 273 +111 4 0 267 312 262 273 +112 4 0 206 179 322 245 +113 4 0 242 245 206 308 +114 4 0 144 319 159 157 +115 4 0 265 308 266 272 +116 4 0 218 219 392 233 +117 4 0 264 324 316 271 +118 4 0 324 308 264 316 +119 4 0 297 318 117 131 +120 4 0 128 117 318 124 +121 4 0 354 207 201 177 +122 4 0 207 177 354 184 +123 4 0 155 163 353 203 +124 4 0 131 297 156 130 +125 4 0 395 330 236 202 +126 4 0 164 142 318 190 +127 4 0 253 314 234 311 +128 4 0 307 314 147 166 +129 4 0 331 234 253 254 +130 4 0 306 236 298 331 +131 4 0 156 297 316 175 +132 4 0 324 319 318 316 +133 4 0 297 324 316 308 +134 4 0 373 314 102 125 +135 4 0 167 155 378 192 +136 4 0 278 324 272 269 +137 4 0 278 276 272 324 +138 4 0 319 159 157 336 +139 4 0 267 257 312 243 +140 4 0 307 215 243 257 +141 4 0 156 297 318 316 +142 4 0 207 354 170 184 +143 4 0 124 144 139 156 +144 4 0 267 312 250 243 +145 4 0 144 151 139 319 +146 4 0 318 316 319 144 +147 4 0 316 139 319 144 +148 4 0 139 144 316 156 +149 4 0 316 191 312 319 +150 4 0 316 191 317 156 +151 4 0 313 308 175 174 +152 4 0 253 234 331 311 +153 4 0 331 395 234 236 +154 4 0 272 265 308 366 +155 4 0 103 140 133 510 +156 4 0 235 199 246 314 +157 4 0 246 237 314 199 +158 4 0 144 151 319 157 +159 4 0 92 157 151 144 +160 4 0 92 159 157 144 +161 4 0 395 234 236 330 +162 4 0 395 330 202 348 +163 4 0 348 330 202 209 +164 4 0 324 312 316 271 +165 4 0 266 308 324 272 +166 4 0 324 366 308 227 +167 4 0 242 264 245 308 +168 4 0 272 266 269 324 +169 4 0 135 151 319 139 +170 4 0 40 35 28 29 +171 4 0 88 148 129 342 +172 4 0 325 342 148 88 +173 4 0 314 116 147 166 +174 4 0 77 353 320 94 +175 4 0 331 262 319 306 +176 4 0 319 317 139 316 +177 4 0 450 329 482 328 +178 4 0 183 307 147 166 +179 4 0 188 361 176 197 +180 4 0 169 179 313 174 +181 4 0 314 196 348 373 +182 4 0 102 84 116 353 +183 4 0 102 77 84 353 +184 4 0 191 147 319 317 +185 4 0 307 262 257 312 +186 4 0 307 257 246 235 +187 4 0 307 257 262 246 +188 4 0 128 318 144 124 +189 4 0 246 314 237 253 +190 4 0 314 203 237 234 +191 4 0 142 128 318 138 +192 4 0 253 237 234 314 +193 4 0 306 319 331 336 +194 4 0 307 314 235 246 +195 4 0 316 250 312 191 +196 4 0 450 403 349 329 +197 4 0 121 297 101 143 +198 4 0 382 164 101 297 +199 4 0 369 198 322 193 +200 4 0 264 266 324 269 +201 4 0 322 354 170 207 +202 4 0 322 170 193 207 +203 4 0 353 84 116 110 +204 4 0 70 302 68 83 +205 4 0 331 311 234 395 +206 4 0 323 493 282 301 +207 4 0 269 278 324 271 +208 4 0 278 312 324 271 +209 4 0 207 170 180 184 +210 4 0 207 170 193 180 +211 4 0 325 130 175 308 +212 4 0 146 354 170 154 +213 4 0 354 302 342 146 +214 4 0 161 348 510 181 +215 4 0 182 314 199 235 +216 4 0 322 354 369 170 +217 4 0 231 207 322 198 +218 4 0 313 322 375 341 +219 4 0 375 361 341 322 +220 4 0 322 207 193 198 +221 4 0 297 143 164 101 +222 4 0 221 213 240 232 +223 4 0 190 188 308 297 +224 4 0 341 361 375 382 +225 4 0 341 308 313 322 +226 4 0 134 158 184 354 +227 4 0 247 308 261 249 +228 4 0 263 308 260 251 +229 4 0 318 319 159 144 +230 4 0 309 262 306 319 +231 4 0 250 204 243 312 +232 4 0 448 192 167 378 +233 4 0 37 333 620 35 +234 4 0 37 33 333 35 +235 4 0 297 318 316 324 +236 4 0 167 448 378 153 +237 4 0 212 218 233 219 +238 4 0 88 325 342 494 +239 4 0 246 307 314 253 +240 4 0 307 253 246 262 +241 4 0 126 311 150 348 +242 4 0 388 611 336 514 +243 4 0 348 234 420 314 +244 4 0 236 254 331 306 +245 4 0 348 314 311 234 +246 4 0 211 308 360 417 +247 4 0 373 102 320 125 +248 4 0 316 250 191 438 +249 4 0 250 205 191 438 +250 4 0 254 262 306 309 +251 4 0 254 309 306 310 +252 4 0 299 254 306 310 +253 4 0 331 262 306 254 +254 4 0 292 294 295 293 +255 4 0 194 307 215 204 +256 4 0 304 306 384 299 +257 4 0 267 312 257 262 +258 4 0 353 192 378 155 +259 4 0 319 159 336 195 +260 4 0 353 192 373 378 +261 4 0 336 185 388 195 +262 4 0 312 250 271 267 +263 4 0 271 250 312 316 +264 4 0 261 249 308 265 +265 4 0 268 308 265 261 +266 4 0 247 308 249 228 +267 4 0 227 195 324 226 +268 4 0 366 324 415 337 +269 4 0 337 366 324 357 +270 4 0 190 195 318 324 +271 4 0 156 318 124 144 +272 4 0 263 266 308 264 +273 4 0 251 263 308 264 +274 4 0 197 198 322 369 +275 4 0 154 354 369 342 +276 4 0 188 308 228 227 +277 4 0 79 328 138 92 +278 4 0 316 317 139 156 +279 4 0 360 175 308 174 +280 4 0 255 251 308 322 +281 4 0 255 256 252 308 +282 4 0 247 228 231 308 +283 4 0 247 308 231 256 +284 4 0 134 149 394 354 +285 4 0 83 162 96 302 +286 4 0 161 373 140 348 +287 4 0 88 67 302 68 +288 4 0 302 97 88 68 +289 4 0 512 166 314 182 +290 4 0 420 192 314 234 +291 4 0 348 330 420 234 +292 4 0 192 314 234 203 +293 4 0 91 123 105 115 +294 4 0 394 70 302 81 +295 4 0 309 273 262 319 +296 4 0 319 262 312 273 +297 4 0 67 302 68 70 +298 4 0 271 278 312 267 +299 4 0 66 57 326 58 +300 4 0 188 136 176 361 +301 4 0 157 331 185 504 +302 4 0 136 361 188 164 +303 4 0 244 250 271 316 +304 4 0 71 302 67 70 +305 4 0 244 213 232 240 +306 4 0 81 302 71 70 +307 4 0 354 149 108 146 +308 4 0 314 237 203 199 +309 4 0 506 378 435 629 +310 4 0 244 438 316 213 +311 4 0 97 302 169 162 +312 4 0 244 316 438 250 +313 4 0 313 129 342 169 +314 4 0 382 113 101 164 +315 4 0 506 435 378 94 +316 4 0 91 123 85 105 +317 4 0 308 264 245 251 +318 4 0 242 264 308 316 +319 4 0 450 349 482 329 +320 4 0 314 373 348 125 +321 4 0 92 138 159 144 +322 4 0 395 311 234 348 +323 4 0 278 273 324 312 +324 4 0 373 378 435 320 +325 4 0 147 311 319 135 +326 4 0 126 311 135 150 +327 4 0 126 135 311 147 +328 4 0 314 348 311 126 +329 4 0 83 302 82 70 +330 4 0 378 435 629 373 +331 4 0 195 159 165 318 +332 4 0 316 312 324 319 +333 4 0 156 175 316 387 +334 4 0 336 298 514 331 +335 4 0 88 342 129 302 +336 4 0 319 307 331 311 +337 4 0 253 314 311 307 +338 4 0 311 331 253 307 +339 4 0 297 341 308 130 +340 4 0 314 348 126 125 +341 4 0 147 314 311 126 +342 4 0 61 339 99 338 +343 4 0 250 204 312 191 +344 4 0 305 185 508 331 +345 4 0 211 242 308 316 +346 4 0 211 308 417 316 +347 4 0 213 316 211 417 +348 4 0 214 215 230 204 +349 4 0 244 316 242 211 +350 4 0 244 211 213 316 +351 4 0 465 501 344 502 +352 4 0 108 354 302 394 +353 4 0 313 129 148 342 +354 4 0 337 324 415 248 +355 4 0 337 258 366 357 +356 4 0 121 101 297 111 +357 4 0 382 101 111 297 +358 4 0 157 159 185 336 +359 4 0 226 336 195 324 +360 4 0 307 262 331 253 +361 4 0 307 262 319 331 +362 4 0 331 254 253 262 +363 4 0 248 336 552 296 +364 4 0 319 324 195 336 +365 4 0 248 296 226 336 +366 4 0 324 248 336 552 +367 4 0 147 183 191 307 +368 4 0 282 281 276 323 +369 4 0 281 323 282 301 +370 4 0 109 119 105 122 +371 4 0 297 143 117 318 +372 4 0 109 122 105 80 +373 4 0 308 366 324 272 +374 4 0 297 318 324 190 +375 4 0 297 190 164 318 +376 4 0 214 204 230 212 +377 4 0 224 212 214 230 +378 4 0 297 143 318 164 +379 4 0 264 308 324 266 +380 4 0 264 269 324 271 +381 4 0 132 117 143 318 +382 4 0 130 297 341 120 +383 4 0 341 130 120 98 +384 4 0 277 343 356 279 +385 4 0 325 308 175 313 +386 4 0 109 81 108 122 +387 4 0 109 122 108 146 +388 4 0 348 234 395 330 +389 4 0 341 111 120 297 +390 4 0 341 100 98 120 +391 4 0 341 111 100 120 +392 4 0 226 336 324 248 +393 4 0 318 319 324 195 +394 4 0 275 270 324 309 +395 4 0 309 336 324 319 +396 4 0 552 270 336 324 +397 4 0 273 309 275 324 +398 4 0 403 328 329 450 +399 4 0 382 111 341 297 +400 4 0 361 322 308 341 +401 4 0 361 341 308 297 +402 4 0 342 85 73 90 +403 4 0 342 73 85 80 +404 4 0 323 324 366 276 +405 4 0 361 297 164 382 +406 4 0 96 82 83 302 +407 4 0 45 647 44 42 +408 4 0 179 354 201 177 +409 4 0 53 621 54 347 +410 4 0 117 124 131 318 +411 4 0 156 144 316 318 +412 4 0 369 198 193 141 +413 4 0 342 302 88 67 +414 4 0 67 80 342 302 +415 4 0 73 80 342 67 +416 4 0 342 73 67 76 +417 4 0 372 528 289 285 +418 4 0 285 528 289 287 +419 4 0 355 98 325 494 +420 4 0 122 119 105 123 +421 4 0 394 82 134 302 +422 4 0 494 88 76 342 +423 4 0 109 81 122 80 +424 4 0 447 580 503 505 +425 4 0 114 118 141 145 +426 4 0 311 150 319 135 +427 4 0 108 122 302 146 +428 4 0 204 307 183 194 +429 4 0 191 204 307 183 +430 4 0 382 101 100 111 +431 4 0 382 111 100 341 +432 4 0 318 159 138 144 +433 4 0 588 281 301 356 +434 4 0 87 61 77 57 +435 4 0 318 159 165 138 +436 4 0 7 12 2 486 +437 4 0 316 191 319 317 +438 4 0 208 196 449 445 +439 4 0 322 369 354 313 +440 4 0 354 158 177 162 +441 4 0 354 169 162 179 +442 4 0 313 369 354 342 +443 4 0 179 162 354 177 +444 4 0 130 98 341 355 +445 4 0 325 130 341 355 +446 4 0 337 357 324 248 +447 4 0 324 357 227 248 +448 4 0 588 281 464 301 +449 4 0 375 341 382 98 +450 4 0 454 75 61 155 +451 4 0 353 77 84 74 +452 4 0 331 305 185 504 +453 4 0 311 331 319 150 +454 4 0 378 339 167 106 +455 4 0 318 190 142 165 +456 4 0 138 142 165 318 +457 4 0 18 12 397 14 +458 4 0 298 514 331 513 +459 4 0 118 137 141 168 +460 4 0 298 331 236 395 +461 4 0 395 298 331 513 +462 4 0 93 157 92 159 +463 4 0 354 158 184 177 +464 4 0 151 157 92 93 +465 4 0 78 93 151 92 +466 4 0 378 448 629 153 +467 4 0 102 314 126 125 +468 4 0 126 116 314 102 +469 4 0 61 72 303 75 +470 4 0 39 461 350 553 +471 4 0 350 39 33 461 +472 4 0 311 331 513 395 +473 4 0 311 331 305 509 +474 4 0 353 102 314 116 +475 4 0 204 215 243 307 +476 4 0 106 153 167 378 +477 4 0 97 162 83 302 +478 4 0 107 353 199 512 +479 4 0 297 188 164 190 +480 4 0 147 319 139 135 +481 4 0 77 353 87 74 +482 4 0 353 203 199 314 +483 4 0 512 314 353 199 +484 4 0 37 38 29 35 +485 4 0 485 140 373 125 +486 4 0 398 448 373 196 +487 4 0 196 570 373 398 +488 4 0 324 248 552 415 +489 4 0 415 270 552 324 +490 4 0 52 57 594 564 +491 4 0 285 289 414 287 +492 4 0 438 250 205 240 +493 4 0 524 425 25 17 +494 4 0 29 25 524 425 +495 4 0 87 77 61 353 +496 4 0 93 92 138 159 +497 4 0 93 92 79 138 +498 4 0 203 192 353 155 +499 4 0 192 353 314 203 +500 4 0 88 302 129 97 +501 4 0 169 342 354 302 +502 4 0 147 319 317 139 +503 4 0 435 426 629 373 +504 4 0 197 168 369 176 +505 4 0 369 176 361 197 +506 4 0 157 151 319 150 +507 4 0 307 319 312 191 +508 4 0 312 307 191 204 +509 4 0 628 373 441 374 +510 4 0 513 331 311 509 +511 4 0 49 594 413 46 +512 4 0 303 163 87 61 +513 4 0 146 342 154 122 +514 4 0 274 366 415 337 +515 4 0 274 258 366 337 +516 4 0 87 57 74 66 +517 4 0 304 306 336 384 +518 4 0 204 250 205 191 +519 4 0 110 74 66 87 +520 4 0 163 87 61 353 +521 4 0 204 205 250 241 +522 4 0 387 438 213 316 +523 4 0 150 160 348 311 +524 4 0 313 369 342 375 +525 4 0 313 322 369 375 +526 4 0 97 129 169 302 +527 4 0 504 305 393 150 +528 4 0 181 348 500 187 +529 4 0 610 527 42 44 +530 4 0 44 527 42 620 +531 4 0 311 305 456 509 +532 4 0 311 509 456 516 +533 4 0 365 512 166 116 +534 4 0 116 512 166 314 +535 4 0 509 305 508 331 +536 4 0 322 369 193 170 +537 4 0 535 526 581 632 +538 4 0 182 314 512 199 +539 4 0 497 441 373 540 +540 4 0 37 42 46 527 +541 4 0 500 209 187 348 +542 4 0 312 257 307 243 +543 4 0 323 366 281 276 +544 4 0 348 420 209 196 +545 4 0 366 279 276 272 +546 4 0 202 500 186 348 +547 4 0 386 406 221 232 +548 4 0 64 526 62 489 +549 4 0 336 159 185 195 +550 4 0 404 24 559 335 +551 4 0 404 24 607 559 +552 4 0 384 336 552 270 +553 4 0 244 240 438 213 +554 4 0 244 438 240 250 +555 4 0 430 461 620 333 +556 4 0 461 333 35 620 +557 4 0 61 564 64 334 +558 4 0 381 437 47 413 +559 4 0 279 277 265 258 +560 4 0 279 277 258 274 +561 4 0 186 500 181 348 +562 4 0 140 510 348 160 +563 4 0 377 410 36 350 +564 4 0 202 330 236 209 +565 4 0 380 345 614 468 +566 4 0 99 339 378 106 +567 4 0 378 106 418 99 +568 4 0 378 448 373 629 +569 4 0 194 235 307 182 +570 4 0 194 307 166 182 +571 4 0 194 307 183 166 +572 4 0 353 373 320 378 +573 4 0 68 97 83 302 +574 4 0 347 496 604 476 +575 4 0 161 181 411 373 +576 4 0 570 374 400 368 +577 4 0 40 38 35 29 +578 4 0 364 289 327 528 +579 4 0 324 309 319 273 +580 4 0 353 378 320 94 +581 4 0 358 91 471 375 +582 4 0 134 394 302 354 +583 4 0 394 149 108 354 +584 4 0 172 354 146 149 +585 4 0 382 358 471 375 +586 4 0 101 382 90 358 +587 4 0 651 346 638 390 +588 4 0 382 90 100 101 +589 4 0 334 594 564 475 +590 4 0 369 361 375 322 +591 4 0 322 197 369 361 +592 4 0 342 325 98 494 +593 4 0 325 313 148 342 +594 4 0 342 325 375 98 +595 4 0 115 369 123 367 +596 4 0 342 98 76 494 +597 4 0 369 375 576 115 +598 4 0 353 512 116 314 +599 4 0 336 304 552 296 +600 4 0 336 306 304 298 +601 4 0 226 514 336 296 +602 4 0 108 302 81 394 +603 4 0 181 411 373 374 +604 4 0 26 440 571 383 +605 4 0 26 383 346 440 +606 4 0 211 360 308 206 +607 4 0 87 74 57 77 +608 4 0 358 113 101 382 +609 4 0 195 388 336 226 +610 4 0 241 233 218 238 +611 4 0 155 339 378 353 +612 4 0 345 79 468 476 +613 4 0 213 316 417 175 +614 4 0 387 316 213 175 +615 4 0 312 307 262 319 +616 4 0 435 485 426 373 +617 4 0 435 373 125 485 +618 4 0 299 310 306 384 +619 4 0 26 425 25 34 +620 4 0 118 114 367 434 +621 4 0 26 34 25 608 +622 4 0 223 222 529 392 +623 4 0 527 38 37 35 +624 4 0 37 527 46 38 +625 4 0 342 123 90 375 +626 4 0 342 123 85 90 +627 4 0 335 350 33 35 +628 4 0 350 461 33 35 +629 4 0 85 91 90 123 +630 4 0 259 247 308 261 +631 4 0 629 628 448 373 +632 4 0 633 142 328 128 +633 4 0 629 497 628 373 +634 4 0 303 61 87 72 +635 4 0 236 254 234 331 +636 4 0 341 98 325 355 +637 4 0 373 570 400 569 +638 4 0 398 570 373 569 +639 4 0 49 413 527 46 +640 4 0 49 46 527 457 +641 4 0 49 626 48 527 +642 4 0 241 204 243 250 +643 4 0 49 527 48 457 +644 4 0 392 218 233 238 +645 4 0 233 392 238 223 +646 4 0 178 198 197 141 +647 4 0 198 197 141 369 +648 4 0 364 290 287 528 +649 4 0 419 381 564 413 +650 4 0 92 78 79 59 +651 4 0 192 373 314 353 +652 4 0 386 406 238 423 +653 4 0 367 369 137 391 +654 4 0 437 413 419 606 +655 4 0 413 437 47 606 +656 4 0 239 252 322 255 +657 4 0 454 61 339 155 +658 4 0 34 466 425 29 +659 4 0 221 386 232 240 +660 4 0 60 64 489 484 +661 4 0 484 65 60 64 +662 4 0 212 386 218 221 +663 4 0 241 240 386 212 +664 4 0 241 205 240 212 +665 4 0 607 24 16 470 +666 4 0 620 42 37 527 +667 4 0 37 333 42 620 +668 4 0 95 87 66 69 +669 4 0 113 164 382 361 +670 4 0 410 30 432 21 +671 4 0 371 1 522 458 +672 4 0 527 47 43 40 +673 4 0 596 425 17 15 +674 4 0 393 456 160 311 +675 4 0 110 95 87 66 +676 4 0 160 311 456 516 +677 4 0 512 511 365 166 +678 4 0 353 511 365 512 +679 4 0 128 144 318 138 +680 4 0 341 130 325 308 +681 4 0 87 61 57 58 +682 4 0 419 58 564 72 +683 4 0 414 289 327 364 +684 4 0 320 378 435 94 +685 4 0 364 528 287 289 +686 4 0 212 221 205 240 +687 4 0 134 172 149 354 +688 4 0 134 172 354 184 +689 4 0 319 147 191 307 +690 4 0 589 641 606 436 +691 4 0 347 79 59 476 +692 4 0 345 79 476 92 +693 4 0 92 138 144 328 +694 4 0 86 92 144 328 +695 4 0 32 399 34 38 +696 4 0 306 309 336 310 +697 4 0 347 604 468 476 +698 4 0 347 468 79 476 +699 4 0 614 345 79 468 +700 4 0 384 310 336 270 +701 4 0 439 25 26 422 +702 4 0 196 192 314 420 +703 4 0 348 420 196 314 +704 4 0 132 143 142 318 +705 4 0 164 142 143 318 +706 4 0 386 406 423 221 +707 4 0 35 527 38 40 +708 4 0 158 354 96 162 +709 4 0 169 302 354 162 +710 4 0 334 475 564 363 +711 4 0 155 61 303 75 +712 4 0 94 353 378 339 +713 4 0 224 233 219 212 +714 4 0 214 215 204 194 +715 4 0 204 243 230 241 +716 4 0 204 230 212 241 +717 4 0 391 474 369 136 +718 4 0 286 588 528 356 +719 4 0 35 620 527 47 +720 4 0 136 474 361 565 +721 4 0 566 526 632 64 +722 4 0 490 439 11 14 +723 4 0 209 330 420 348 +724 4 0 35 527 40 47 +725 4 0 76 342 73 98 +726 4 0 77 353 102 320 +727 4 0 268 308 261 260 +728 4 0 167 155 339 378 +729 4 0 465 289 385 344 +730 4 0 255 308 260 259 +731 4 0 335 24 470 33 +732 4 0 559 24 470 335 +733 4 0 522 1 371 428 +734 4 0 347 53 496 54 +735 4 0 559 24 607 470 +736 4 0 476 347 496 54 +737 4 0 312 204 243 307 +738 4 0 230 215 243 204 +739 4 0 241 218 212 386 +740 4 0 241 238 218 386 +741 4 0 29 33 28 23 +742 4 0 23 335 559 470 +743 4 0 297 382 361 341 +744 4 0 336 611 185 331 +745 4 0 388 185 336 611 +746 4 0 353 373 102 320 +747 4 0 373 102 314 353 +748 4 0 44 527 606 610 +749 4 0 74 110 84 353 +750 4 0 610 527 606 413 +751 4 0 325 341 375 98 +752 4 0 369 136 137 391 +753 4 0 169 354 342 313 +754 4 0 274 366 279 281 +755 4 0 281 366 279 276 +756 4 0 322 313 206 308 +757 4 0 414 289 344 385 +758 4 0 114 546 367 434 +759 4 0 367 391 434 369 +760 4 0 155 163 303 61 +761 4 0 47 620 527 44 +762 4 0 384 304 552 336 +763 4 0 384 310 306 336 +764 4 0 99 378 339 94 +765 4 0 506 94 378 99 +766 4 0 365 353 512 116 +767 4 0 378 99 418 506 +768 4 0 478 23 559 470 +769 4 0 328 86 633 128 +770 4 0 265 308 268 266 +771 4 0 268 308 263 266 +772 4 0 564 419 436 58 +773 4 0 460 75 564 65 +774 4 0 339 61 99 94 +775 4 0 518 564 65 460 +776 4 0 643 216 229 392 +777 4 0 342 88 76 67 +778 4 0 26 422 11 439 +779 4 0 26 440 439 571 +780 4 0 411 161 373 441 +781 4 0 442 467 412 10 +782 4 0 350 377 24 33 +783 4 0 225 409 217 223 +784 4 0 410 377 24 350 +785 4 0 24 350 33 335 +786 4 0 371 522 523 458 +787 4 0 278 324 273 276 +788 4 0 273 324 275 276 +789 4 0 170 354 172 184 +790 4 0 169 179 354 313 +791 4 0 607 16 24 580 +792 4 0 367 391 137 118 +793 4 0 35 620 37 527 +794 4 0 548 33 461 333 +795 4 0 414 385 344 294 +796 4 0 414 289 288 344 +797 4 0 65 64 484 454 +798 4 0 93 79 78 401 +799 4 0 375 382 358 90 +800 4 0 413 575 564 594 +801 4 0 187 181 368 189 +802 4 0 358 375 90 91 +803 4 0 275 276 324 323 +804 4 0 493 270 323 275 +805 4 0 532 323 276 275 +806 4 0 324 270 323 415 +807 4 0 275 323 324 270 +808 4 0 157 331 319 336 +809 4 0 454 339 61 338 +810 4 0 527 47 507 43 +811 4 0 74 87 110 353 +812 4 0 61 353 339 155 +813 4 0 444 445 618 379 +814 4 0 173 133 160 510 +815 4 0 352 604 468 347 +816 4 0 161 181 373 348 +817 4 0 23 335 470 33 +818 4 0 181 187 374 373 +819 4 0 29 35 28 33 +820 4 0 348 187 181 373 +821 4 0 562 10 412 447 +822 4 0 10 580 503 447 +823 4 0 399 351 34 38 +824 4 0 515 592 399 32 +825 4 0 434 112 637 474 +826 4 0 134 82 96 302 +827 4 0 224 230 233 212 +828 4 0 134 302 96 354 +829 4 0 302 354 162 96 +830 4 0 376 64 60 564 +831 4 0 606 640 589 45 +832 4 0 369 137 168 141 +833 4 0 113 361 583 136 +834 4 0 197 369 168 141 +835 4 0 12 7 4 14 +836 4 0 510 181 173 171 +837 4 0 61 339 353 94 +838 4 0 369 154 170 354 +839 4 0 404 607 24 21 +840 4 0 411 374 578 441 +841 4 0 500 186 189 480 +842 4 0 535 526 632 566 +843 4 0 628 441 497 483 +844 4 0 478 23 28 559 +845 4 0 28 335 559 23 +846 4 0 93 92 78 79 +847 4 0 554 473 631 453 +848 4 0 198 178 193 141 +849 4 0 187 444 209 500 +850 4 0 226 388 336 514 +851 4 0 287 464 285 528 +852 4 0 528 301 285 372 +853 4 0 497 629 426 373 +854 4 0 394 302 70 82 +855 4 0 64 61 454 75 +856 4 0 444 587 618 445 +857 4 0 467 458 371 523 +858 4 0 371 523 520 467 +859 4 0 371 520 551 467 +860 4 0 385 465 294 292 +861 4 0 468 604 345 476 +862 4 0 584 517 63 345 +863 4 0 176 136 137 369 +864 4 0 439 440 18 571 +865 4 0 490 26 11 439 +866 4 0 324 366 227 357 +867 4 0 606 413 419 436 +868 4 0 527 48 477 507 +869 4 0 527 477 48 457 +870 4 0 527 492 48 507 +871 4 0 527 626 48 492 +872 4 0 134 354 96 158 +873 4 0 62 64 489 60 +874 4 0 52 57 370 594 +875 4 0 326 52 55 564 +876 4 0 524 425 17 19 +877 4 0 373 441 161 540 +878 4 0 373 161 140 540 +879 4 0 66 326 55 58 +880 4 0 58 326 55 564 +881 4 0 310 309 336 270 +882 4 0 324 270 336 309 +883 4 0 157 336 185 331 +884 4 0 181 411 171 161 +885 4 0 640 589 641 606 +886 4 0 537 557 621 54 +887 4 0 282 285 340 288 +888 4 0 372 285 288 340 +889 4 0 382 100 98 341 +890 4 0 502 294 465 292 +891 4 0 43 34 351 38 +892 4 0 221 240 213 205 +893 4 0 438 240 205 213 +894 4 0 425 466 524 29 +895 4 0 354 302 146 108 +896 4 0 435 426 506 629 +897 4 0 497 506 426 629 +898 4 0 187 181 374 368 +899 4 0 517 79 614 345 +900 4 0 342 90 73 98 +901 4 0 180 141 178 152 +902 4 0 178 152 141 168 +903 4 0 193 180 141 178 +904 4 0 140 161 348 510 +905 4 0 9 442 13 362 +906 4 0 442 9 13 467 +907 4 0 408 505 503 580 +908 4 0 607 580 408 16 +909 4 0 327 289 414 385 +910 4 0 372 284 283 340 +911 4 0 359 89 526 566 +912 4 0 607 539 478 470 +913 4 0 140 373 125 348 +914 4 0 328 86 92 517 +915 4 0 527 47 44 606 +916 4 0 155 163 61 353 +917 4 0 367 391 118 434 +918 4 0 338 64 61 454 +919 4 0 64 338 484 454 +920 4 0 359 89 566 338 +921 4 0 489 526 566 64 +922 4 0 448 192 378 373 +923 4 0 350 39 377 33 +924 4 0 369 137 176 168 +925 4 0 377 350 553 39 +926 4 0 325 313 375 341 +927 4 0 340 288 625 282 +928 4 0 342 313 375 325 +929 4 0 524 466 19 20 +930 4 0 425 466 19 524 +931 4 0 348 395 186 202 +932 4 0 610 44 42 45 +933 4 0 409 433 217 223 +934 4 0 217 433 529 223 +935 4 0 582 375 471 115 +936 4 0 434 474 637 369 +937 4 0 382 375 471 582 +938 4 0 98 90 382 375 +939 4 0 382 100 90 98 +940 4 0 123 105 122 85 +941 4 0 122 85 105 80 +942 4 0 43 40 34 38 +943 4 0 369 474 361 136 +944 4 0 469 452 564 460 +945 4 0 46 41 527 457 +946 4 0 415 366 274 323 +947 4 0 191 387 316 438 +948 4 0 191 387 156 316 +949 4 0 434 391 474 369 +950 4 0 502 294 344 465 +951 4 0 502 294 292 293 +952 4 0 476 59 92 79 +953 4 0 306 309 319 336 +954 4 0 528 301 464 285 +955 4 0 301 282 464 285 +956 4 0 208 449 210 379 +957 4 0 210 379 220 208 +958 4 0 551 520 10 467 +959 4 0 359 89 339 106 +960 4 0 110 353 365 116 +961 4 0 353 511 110 365 +962 4 0 118 141 145 152 +963 4 0 34 28 466 29 +964 4 0 621 347 59 54 +965 4 0 59 621 79 347 +966 4 0 342 80 122 302 +967 4 0 369 123 154 342 +968 4 0 123 85 122 342 +969 4 0 122 342 85 80 +970 4 0 450 349 612 482 +971 4 0 564 55 436 413 +972 4 0 40 38 29 34 +973 4 0 606 641 413 436 +974 4 0 28 35 335 33 +975 4 0 34 25 32 29 +976 4 0 487 548 495 479 +977 4 0 187 209 196 348 +978 4 0 461 479 430 495 +979 4 0 311 513 509 186 +980 4 0 395 311 348 186 +981 4 0 187 196 209 444 +982 4 0 485 540 426 373 +983 4 0 21 580 24 447 +984 4 0 412 447 21 562 +985 4 0 412 562 21 446 +986 4 0 447 580 24 10 +987 4 0 46 527 610 413 +988 4 0 229 392 216 222 +989 4 0 323 281 366 274 +990 4 0 281 301 274 323 +991 4 0 599 625 429 282 +992 4 0 608 25 32 34 +993 4 0 372 288 284 340 +994 4 0 227 324 190 308 +995 4 0 373 196 348 187 +996 4 0 425 25 34 29 +997 4 0 628 448 373 591 +998 4 0 591 448 373 398 +999 4 0 477 43 41 527 +1000 4 0 80 71 81 302 +1001 4 0 457 477 41 527 +1002 4 0 647 487 430 479 +1003 4 0 628 373 497 441 +1004 4 0 578 628 441 374 +1005 4 0 410 24 335 350 +1006 4 0 393 311 160 150 +1007 4 0 367 118 137 141 +1008 4 0 343 488 356 396 +1009 4 0 87 72 61 58 +1010 4 0 488 588 356 396 +1011 4 0 476 54 59 347 +1012 4 0 94 353 61 77 +1013 4 0 110 353 87 107 +1014 4 0 251 245 322 201 +1015 4 0 245 179 322 201 +1016 4 0 11 422 486 14 +1017 4 0 287 588 464 528 +1018 4 0 10 467 412 551 +1019 4 0 13 551 412 467 +1020 4 0 371 467 551 13 +1021 4 0 551 10 8 412 +1022 4 0 113 164 361 136 +1023 4 0 425 25 15 26 +1024 4 0 140 348 125 160 +1025 4 0 451 588 528 286 +1026 4 0 180 152 145 141 +1027 4 0 607 16 539 470 +1028 4 0 374 570 400 373 +1029 4 0 373 374 556 400 +1030 4 0 374 373 556 628 +1031 4 0 441 628 578 483 +1032 4 0 497 642 418 629 +1033 4 0 167 89 106 339 +1034 4 0 346 440 390 521 +1035 4 0 369 123 342 375 +1036 4 0 583 382 498 361 +1037 4 0 564 75 72 61 +1038 4 0 564 61 64 75 +1039 4 0 345 517 79 92 +1040 4 0 533 529 223 222 +1041 4 0 498 582 576 375 +1042 4 0 575 376 609 49 +1043 4 0 412 10 8 447 +1044 4 0 561 472 549 468 +1045 4 0 239 322 252 231 +1046 4 0 397 12 4 14 +1047 4 0 367 369 434 576 +1048 4 0 206 313 322 179 +1049 4 0 322 179 313 354 +1050 4 0 12 2 4 7 +1051 4 0 346 638 26 608 +1052 4 0 66 87 57 58 +1053 4 0 72 58 564 61 +1054 4 0 322 207 231 239 +1055 4 0 201 354 322 207 +1056 4 0 239 255 322 201 +1057 4 0 533 402 529 222 +1058 4 0 60 518 564 65 +1059 4 0 11 486 12 14 +1060 4 0 118 168 141 152 +1061 4 0 60 376 564 518 +1062 4 0 576 375 582 115 +1063 4 0 515 34 399 351 +1064 4 0 334 564 64 363 +1065 4 0 311 331 150 305 +1066 4 0 473 538 597 519 +1067 4 0 564 594 575 475 +1068 4 0 36 30 432 410 +1069 4 0 343 396 356 279 +1070 4 0 281 279 356 396 +1071 4 0 281 274 301 356 +1072 4 0 486 7 14 422 +1073 4 0 642 153 585 629 +1074 4 0 153 642 628 629 +1075 4 0 503 447 8 10 +1076 4 0 461 430 620 416 +1077 4 0 493 270 275 280 +1078 4 0 275 493 532 323 +1079 4 0 532 493 282 323 +1080 4 0 461 495 430 416 +1081 4 0 493 532 280 275 +1082 4 0 389 381 47 413 +1083 4 0 49 413 626 527 +1084 4 0 500 189 186 181 +1085 4 0 498 382 582 375 +1086 4 0 410 30 24 377 +1087 4 0 30 410 36 377 +1088 4 0 366 265 279 272 +1089 4 0 608 34 32 31 +1090 4 0 527 40 43 38 +1091 4 0 46 527 41 38 +1092 4 0 43 527 38 41 +1093 4 0 597 639 7 486 +1094 4 0 306 298 336 331 +1095 4 0 11 26 15 543 +1096 4 0 554 11 15 543 +1097 4 0 416 430 620 649 +1098 4 0 291 290 364 327 +1099 4 0 637 498 375 361 +1100 4 0 39 548 33 461 +1101 4 0 422 634 25 543 +1102 4 0 583 582 382 113 +1103 4 0 367 114 118 141 +1104 4 0 473 422 11 554 +1105 4 0 178 197 168 141 +1106 4 0 375 369 123 115 +1107 4 0 91 123 115 375 +1108 4 0 377 350 36 553 +1109 4 0 173 181 516 186 +1110 4 0 110 95 107 87 +1111 4 0 353 107 163 87 +1112 4 0 46 527 42 610 +1113 4 0 500 209 348 202 +1114 4 0 334 61 564 57 +1115 4 0 510 103 140 161 +1116 4 0 160 104 140 133 +1117 4 0 486 11 473 422 +1118 4 0 336 611 331 514 +1119 4 0 576 434 637 369 +1120 4 0 29 466 524 20 +1121 4 0 366 279 265 258 +1122 4 0 366 279 258 274 +1123 4 0 89 484 338 454 +1124 4 0 462 621 568 534 +1125 4 0 133 104 140 103 +1126 4 0 462 534 568 531 +1127 4 0 521 440 390 563 +1128 4 0 383 440 563 390 +1129 4 0 141 154 170 369 +1130 4 0 141 193 369 170 +1131 4 0 173 181 510 516 +1132 4 0 348 510 181 516 +1133 4 0 324 366 276 272 +1134 4 0 415 324 366 323 +1135 4 0 477 527 507 43 +1136 4 0 26 25 440 346 +1137 4 0 430 333 42 479 +1138 4 0 460 452 564 75 +1139 4 0 31 515 32 592 +1140 4 0 181 189 187 500 +1141 4 0 389 527 413 47 +1142 4 0 413 389 626 527 +1143 4 0 376 590 49 575 +1144 4 0 331 611 185 508 +1145 4 0 223 392 407 219 +1146 4 0 223 233 392 219 +1147 4 0 538 648 597 519 +1148 4 0 597 648 538 486 +1149 4 0 557 537 568 499 +1150 4 0 553 39 461 416 +1151 4 0 290 528 451 287 +1152 4 0 554 453 332 560 +1153 4 0 601 467 458 9 +1154 4 0 623 525 535 566 +1155 4 0 566 525 535 526 +1156 4 0 378 106 431 418 +1157 4 0 53 496 352 347 +1158 4 0 564 300 419 72 +1159 4 0 564 452 300 72 +1160 4 0 2 6 7 486 +1161 4 0 421 451 528 286 +1162 4 0 451 528 588 287 +1163 4 0 409 595 433 491 +1164 4 0 79 621 78 401 +1165 4 0 401 621 78 555 +1166 4 0 78 537 555 621 +1167 4 0 599 340 282 301 +1168 4 0 493 599 282 301 +1169 4 0 430 620 42 333 +1170 4 0 565 498 112 637 +1171 4 0 583 498 112 565 +1172 4 0 599 429 536 282 +1173 4 0 599 625 459 429 +1174 4 0 543 554 332 15 +1175 4 0 474 112 637 565 +1176 4 0 364 290 528 327 +1177 4 0 548 461 479 333 +1178 4 0 461 333 430 479 +1179 4 0 383 390 346 440 +1180 4 0 65 60 64 564 +1181 4 0 65 64 75 564 +1182 4 0 383 638 346 390 +1183 4 0 380 468 614 549 +1184 4 0 532 282 276 323 +1185 4 0 157 331 504 150 +1186 4 0 89 454 338 339 +1187 4 0 167 454 89 339 +1188 4 0 8 5 10 551 +1189 4 0 5 520 10 551 +1190 4 0 492 626 545 389 +1191 4 0 389 626 545 469 +1192 4 0 37 33 35 29 +1193 4 0 615 568 499 557 +1194 4 0 500 186 480 202 +1195 4 0 54 56 53 496 +1196 4 0 294 295 291 385 +1197 4 0 295 291 385 327 +1198 4 0 295 294 292 385 +1199 4 0 474 637 361 565 +1200 4 0 497 373 426 540 +1201 4 0 40 29 28 34 +1202 4 0 535 525 581 526 +1203 4 0 328 92 79 517 +1204 4 0 496 56 352 604 +1205 4 0 459 536 646 493 +1206 4 0 459 429 624 536 +1207 4 0 493 536 280 532 +1208 4 0 25 346 26 608 +1209 4 0 351 399 41 38 +1210 4 0 43 41 38 351 +1211 4 0 527 413 47 606 +1212 4 0 308 252 322 231 +1213 4 0 308 255 322 252 +1214 4 0 256 231 252 308 +1215 4 0 256 308 259 247 +1216 4 0 21 30 24 410 +1217 4 0 21 30 562 24 +1218 4 0 315 621 555 568 +1219 4 0 217 219 223 407 +1220 4 0 225 223 219 233 +1221 4 0 407 217 529 223 +1222 4 0 381 452 300 564 +1223 4 0 595 635 433 491 +1224 4 0 414 385 291 327 +1225 4 0 416 39 461 495 +1226 4 0 461 39 548 495 +1227 4 0 461 548 479 495 +1228 4 0 301 282 281 464 +1229 4 0 301 282 285 340 +1230 4 0 315 621 568 462 +1231 4 0 372 289 288 285 +1232 4 0 289 288 285 414 +1233 4 0 431 153 106 378 +1234 4 0 55 641 589 436 +1235 4 0 651 572 638 608 +1236 4 0 564 452 72 75 +1237 4 0 573 534 567 613 +1238 4 0 567 645 600 534 +1239 4 0 499 568 577 537 +1240 4 0 414 327 291 364 +1241 4 0 561 549 614 468 +1242 4 0 338 489 566 64 +1243 4 0 89 484 489 338 +1244 4 0 385 294 465 344 +1245 4 0 445 196 444 209 +1246 4 0 209 550 444 427 +1247 4 0 490 14 11 12 +1248 4 0 490 18 14 12 +1249 4 0 597 648 486 7 +1250 4 0 486 639 7 422 +1251 4 0 639 473 597 631 +1252 4 0 529 491 616 533 +1253 4 0 435 320 125 373 +1254 4 0 616 491 529 541 +1255 4 0 497 628 642 629 +1256 4 0 46 52 413 602 +1257 4 0 623 359 566 338 +1258 4 0 497 506 629 418 +1259 4 0 99 359 623 338 +1260 4 0 65 64 454 75 +1261 4 0 209 617 550 427 +1262 4 0 86 328 144 128 +1263 4 0 570 187 374 368 +1264 4 0 403 86 633 328 +1265 4 0 601 522 458 523 +1266 4 0 604 352 472 56 +1267 4 0 273 312 319 324 +1268 4 0 380 614 63 549 +1269 4 0 561 549 63 614 +1270 4 0 623 525 566 359 +1271 4 0 359 525 566 526 +1272 4 0 566 89 526 489 +1273 4 0 113 382 358 471 +1274 4 0 582 471 382 113 +1275 4 0 523 467 458 601 +1276 4 0 268 308 260 263 +1277 4 0 374 628 556 578 +1278 4 0 498 582 382 583 +1279 4 0 586 645 534 557 +1280 4 0 361 176 369 136 +1281 4 0 277 356 274 279 +1282 4 0 576 637 375 369 +1283 4 0 637 375 369 361 +1284 4 0 373 556 569 400 +1285 4 0 556 373 569 628 +1286 4 0 447 562 24 21 +1287 4 0 47 492 527 507 +1288 4 0 495 39 548 487 +1289 4 0 572 608 651 650 +1290 4 0 541 619 542 574 +1291 4 0 27 562 21 30 +1292 4 0 21 446 562 27 +1293 4 0 517 328 614 79 +1294 4 0 545 530 622 575 +1295 4 0 522 371 523 558 +1296 4 0 523 371 520 558 +1297 4 0 471 91 115 375 +1298 4 0 578 127 628 556 +1299 4 0 127 153 628 556 +1300 4 0 641 413 55 52 +1301 4 0 55 564 436 58 +1302 4 0 564 334 57 594 +1303 4 0 55 641 436 413 +1304 4 0 575 413 49 594 +1305 4 0 15 17 596 560 +1306 4 0 521 440 563 571 +1307 4 0 632 581 62 526 +1308 4 0 285 372 301 340 +1309 4 0 290 451 528 421 +1310 4 0 326 57 564 58 +1311 4 0 205 212 241 204 +1312 4 0 564 452 469 381 +1313 4 0 239 322 207 201 +1314 4 0 223 392 529 407 +1315 4 0 381 564 413 469 +1316 4 0 395 513 311 186 +1317 4 0 389 469 413 626 +1318 4 0 136 361 583 565 +1319 4 0 586 645 567 534 +1320 4 0 32 25 608 346 +1321 4 0 369 367 137 141 +1322 4 0 469 575 545 622 +1323 4 0 593 543 634 422 +1324 4 0 373 569 628 591 +1325 4 0 556 569 153 628 +1326 4 0 196 187 373 570 +1327 4 0 167 454 339 155 +1328 4 0 590 626 575 530 +1329 4 0 536 493 282 532 +1330 4 0 133 140 160 510 +1331 4 0 376 363 64 564 +1332 4 0 209 427 444 587 +1333 4 0 571 440 563 383 +1334 4 0 498 375 576 637 +1335 4 0 531 534 568 579 +1336 4 0 534 568 557 621 +1337 4 0 218 392 643 238 +1338 4 0 568 555 577 537 +1339 4 0 475 609 363 49 +1340 4 0 363 609 475 564 +1341 4 0 393 311 150 305 +1342 4 0 19 425 17 596 +1343 4 0 596 17 603 560 +1344 4 0 522 428 371 558 +1345 4 0 127 628 497 483 +1346 4 0 492 48 545 626 +1347 4 0 21 607 24 580 +1348 4 0 132 117 318 128 +1349 4 0 633 132 547 142 +1350 4 0 437 381 419 413 +1351 4 0 419 381 437 300 +1352 4 0 173 181 186 171 +1353 4 0 405 613 600 534 +1354 4 0 632 526 62 64 +1355 4 0 489 484 64 338 +1356 4 0 600 54 53 621 +1357 4 0 29 20 28 466 +1358 4 0 20 28 466 443 +1359 4 0 49 48 626 590 +1360 4 0 63 345 614 380 +1361 4 0 584 345 63 380 +1362 4 0 470 607 559 478 +1363 4 0 28 23 22 20 +1364 4 0 478 23 22 28 +1365 4 0 473 422 554 631 +1366 4 0 555 537 568 621 +1367 4 0 18 490 14 439 +1368 4 0 596 17 19 603 +1369 4 0 571 440 18 521 +1370 4 0 542 491 616 541 +1371 4 0 534 568 615 557 +1372 4 0 534 568 579 615 +1373 4 0 392 222 229 238 +1374 4 0 626 48 530 590 +1375 4 0 238 406 229 423 +1376 4 0 629 585 642 418 +1377 4 0 418 506 629 378 +1378 4 0 378 431 629 418 +1379 4 0 153 448 628 591 +1380 4 0 591 569 628 153 +1381 4 0 550 209 500 627 +1382 4 0 515 31 32 34 +1383 4 0 209 627 550 617 +1384 4 0 569 556 153 400 +1385 4 0 645 621 557 54 +1386 4 0 529 491 533 223 +1387 4 0 601 1 458 522 +1388 4 0 522 601 1 3 +1389 4 0 359 339 99 106 +1390 4 0 338 99 359 339 +1391 4 0 49 575 626 413 +1392 4 0 473 597 631 453 +1393 4 0 605 564 518 460 +1394 4 0 222 392 402 529 +1395 4 0 113 382 583 361 +1396 4 0 33 335 28 23 +1397 4 0 370 52 594 46 +1398 4 0 408 505 580 607 +1399 4 0 413 640 602 641 +1400 4 0 630 376 564 609 +1401 4 0 49 376 609 363 +1402 4 0 363 376 609 564 +1403 4 0 393 456 311 305 +1404 4 0 218 221 386 643 +1405 4 0 643 386 423 221 +1406 4 0 141 123 369 367 +1407 4 0 498 382 375 361 +1408 4 0 474 637 369 361 +1409 4 0 558 371 520 551 +1410 4 0 558 428 371 551 +1411 4 0 374 441 411 373 +1412 4 0 422 25 26 543 +1413 4 0 25 17 15 634 +1414 4 0 606 44 610 45 +1415 4 0 367 115 369 576 +1416 4 0 367 576 546 115 +1417 4 0 636 573 567 613 +1418 4 0 615 51 579 573 +1419 4 0 50 51 615 636 +1420 4 0 55 413 564 52 +1421 4 0 594 52 413 46 +1422 4 0 564 326 52 57 +1423 4 0 367 434 546 576 +1424 4 0 208 449 379 445 +1425 4 0 379 445 544 208 +1426 4 0 26 439 440 25 +1427 4 0 622 575 605 469 +1428 4 0 636 586 567 573 +1429 4 0 573 586 567 534 +1430 4 0 599 625 340 283 +1431 4 0 605 630 518 564 +1432 4 0 171 510 181 161 +1433 4 0 32 29 38 34 +1434 4 0 402 216 392 222 +1435 4 0 223 222 392 238 +1436 4 0 389 492 527 47 +1437 4 0 389 492 626 527 +1438 4 0 577 555 78 537 +1439 4 0 315 621 401 555 +1440 4 0 15 598 634 560 +1441 4 0 634 17 15 560 +1442 4 0 481 142 328 633 +1443 4 0 128 328 144 138 +1444 4 0 413 610 640 606 +1445 4 0 640 606 610 45 +1446 4 0 379 449 444 445 +1447 4 0 187 449 196 444 +1448 4 0 445 449 444 196 +1449 4 0 605 564 460 469 +1450 4 0 575 564 605 469 +1451 4 0 541 200 619 574 +1452 4 0 564 436 419 413 +1453 4 0 517 482 63 614 +1454 4 0 154 369 141 123 +1455 4 0 583 498 565 361 +1456 4 0 498 361 637 565 +1457 4 0 622 530 630 575 +1458 4 0 21 30 432 27 +1459 4 0 173 510 160 516 +1460 4 0 311 160 348 516 +1461 4 0 485 140 540 373 +1462 4 0 21 505 580 447 +1463 4 0 490 26 439 571 +1464 4 0 379 544 220 208 +1465 4 0 348 516 181 186 +1466 4 0 186 509 311 516 +1467 4 0 209 202 627 617 +1468 4 0 433 635 529 491 +1469 4 0 430 42 620 44 +1470 4 0 649 430 620 44 +1471 4 0 529 635 541 491 +1472 4 0 404 24 410 21 +1473 4 0 404 410 24 335 +1474 4 0 89 338 359 339 +1475 4 0 450 328 482 517 +1476 4 0 517 328 482 614 +1477 4 0 78 59 537 621 +1478 4 0 588 396 281 356 +1479 4 0 286 488 588 356 +1480 4 0 424 543 593 422 +1481 4 0 463 607 408 16 +1482 4 0 389 381 413 469 +1483 4 0 413 469 575 626 +1484 4 0 626 469 575 545 +1485 4 0 554 11 543 422 +1486 4 0 459 624 646 536 +1487 4 0 332 543 593 424 +1488 4 0 631 554 424 422 +1489 4 0 153 431 629 378 +1490 4 0 545 48 530 626 +1491 4 0 626 530 545 575 +1492 4 0 59 621 78 79 +1493 4 0 160 510 348 516 +1494 4 0 626 590 575 49 +1495 4 0 576 434 112 637 +1496 4 0 498 576 112 637 +1497 4 0 346 651 638 608 +1498 4 0 13 442 412 362 +1499 4 0 13 467 412 442 +1500 4 0 132 142 633 128 +1501 4 0 184 180 172 170 +1502 4 0 631 332 424 554 +1503 4 0 531 573 579 51 +1504 4 0 521 571 563 18 +1505 4 0 599 625 282 340 +1506 4 0 622 630 605 575 +1507 4 0 562 442 362 412 +1508 4 0 193 180 170 141 +1509 4 0 50 644 636 615 +1510 4 0 443 466 20 19 +1511 4 0 616 542 533 491 +1512 4 0 413 594 564 52 +1513 4 0 621 53 600 405 +1514 4 0 362 562 446 27 +1515 4 0 403 547 321 481 +1516 4 0 403 481 321 329 +1517 4 0 562 442 412 10 +1518 4 0 493 459 536 599 +1519 4 0 493 599 536 282 +1520 4 0 450 86 328 517 +1521 4 0 413 602 610 46 +1522 4 0 29 23 28 20 +1523 4 0 223 409 433 491 +1524 4 0 621 59 537 54 +1525 4 0 13 362 412 446 +1526 4 0 439 422 11 14 +1527 4 0 639 473 631 422 +1528 4 0 450 612 584 517 +1529 4 0 450 482 612 517 +1530 4 0 413 641 602 52 +1531 4 0 447 10 24 562 +1532 4 0 531 573 534 579 +1533 4 0 380 345 468 604 +1534 4 0 587 427 444 618 +1535 4 0 613 567 600 534 +1536 4 0 218 386 238 643 +1537 4 0 643 238 423 386 +1538 4 0 347 496 352 604 +1539 4 0 63 345 517 614 +1540 4 0 584 612 63 517 +1541 4 0 629 431 585 418 +1542 4 0 153 431 585 629 +1543 4 0 463 539 478 607 +1544 4 0 463 539 607 16 +1545 4 0 564 609 475 575 +1546 4 0 533 529 402 616 +1547 4 0 376 630 564 518 +1548 4 0 645 54 600 621 +1549 4 0 380 468 472 604 +1550 4 0 604 468 472 352 +1551 4 0 380 468 549 472 +1552 4 0 570 187 373 374 +1553 4 0 606 413 641 640 +1554 4 0 413 610 602 640 +1555 4 0 458 467 13 9 +1556 4 0 467 458 13 371 +1557 4 0 11 422 26 543 +1558 4 0 25 17 425 15 +1559 4 0 646 536 280 493 +1560 4 0 646 624 280 536 +1561 4 0 647 430 44 42 +1562 4 0 618 544 220 379 +1563 4 0 648 6 486 7 +1564 4 0 648 6 538 486 +1565 4 0 403 633 547 481 +1566 4 0 403 328 633 481 +1567 4 0 483 127 628 578 +1568 4 0 486 7 12 14 +1569 4 0 53 56 352 496 +1570 4 0 340 288 284 625 +1571 4 0 283 340 284 625 +1572 4 0 561 352 472 468 +1573 4 0 86 450 328 403 +1574 4 0 329 403 481 328 +1575 4 0 455 288 284 372 +1576 4 0 501 288 284 455 +1577 4 0 376 530 575 630 +1578 4 0 630 376 609 575 +1579 4 0 430 479 42 647 +1580 4 0 621 405 600 534 +1581 4 0 22 28 20 443 +1582 4 0 643 238 229 423 +1583 4 0 481 633 547 142 +1584 4 0 558 428 551 652 +1585 4 0 509 611 331 508 +1586 4 0 513 514 331 611 +1587 4 0 509 513 331 611 +1588 4 0 601 9 1 3 +1589 4 0 289 288 344 501 +1590 4 0 515 32 399 34 +1591 4 0 403 321 349 329 +1592 4 0 392 229 643 238 +1593 4 0 618 445 544 379 +1594 4 0 618 587 544 445 +1595 4 0 531 613 534 573 +1596 4 0 629 153 448 628 +1597 4 0 538 473 597 486 +1598 4 0 597 473 639 486 +1599 4 0 650 31 608 346 +1600 4 0 607 505 580 21 +1601 4 0 288 455 289 372 +1602 4 0 289 455 288 501 +1603 4 0 376 530 590 575 +1604 4 0 49 594 475 575 +1605 4 0 356 279 281 274 +1606 4 0 550 209 444 500 +1607 4 0 362 412 446 562 +1608 4 0 529 433 491 223 +1609 4 0 455 372 284 283 +1610 4 0 465 501 455 289 +1611 4 0 465 289 344 501 +1612 4 0 445 209 444 587 +1613 4 0 153 642 127 628 +1614 4 0 294 385 291 414 +1615 4 0 283 625 459 599 +1616 4 0 613 531 51 573 +1617 4 0 636 573 613 51 +1618 4 0 557 621 568 537 +1619 4 0 558 551 520 5 +1620 4 0 500 209 202 627 +1621 4 0 635 200 541 574 +1622 4 0 595 200 635 574 +1623 4 0 558 652 551 5 +1624 4 0 534 579 573 615 +1625 4 0 605 575 630 564 +1626 4 0 31 346 32 608 +1627 4 0 631 424 639 422 +1628 4 0 383 346 638 26 +1629 4 0 469 575 564 413 +1630 4 0 15 560 332 598 +1631 4 0 15 554 332 560 +1632 4 0 586 557 534 615 +1633 4 0 573 586 534 615 +1634 4 0 332 543 598 593 +1635 4 0 543 332 598 15 +1636 4 0 609 575 564 630 +1637 4 0 554 631 332 453 +1638 4 0 424 554 543 422 +1639 4 0 608 346 651 650 +1640 4 0 487 495 430 479 +1641 4 0 645 621 534 557 +1642 4 0 645 621 600 534 +1643 4 0 542 491 541 574 +1644 4 0 541 635 574 491 +1645 4 0 636 644 586 573 +1646 4 0 573 586 615 644 +1647 4 0 543 634 598 593 +1648 4 0 497 127 642 628 +1649 4 0 598 543 15 634 +1650 4 0 25 15 543 634 +1651 4 0 473 519 597 453 +1652 4 0 595 574 635 491 +1653 4 0 636 51 615 573 +1654 4 0 644 573 636 615 +$EndElements +$ElementData +1 +"color" +1 +0.0 +3 +0 +1 +1654 +1 7.56199 +2 4.86806 +3 4.40144 +4 6.42934 +5 4.22059 +6 5.73014 +7 6.38728 +8 6.65278 +9 6.11566 +10 8.59831 +11 4.59846 +12 3.75402 +13 4.81655 +14 5.303 +15 4.23688 +16 4.44352 +17 9.61146 +18 4.02007 +19 6.55381 +20 4.32183 +21 3.77651 +22 4.28126 +23 4.67035 +24 4.25302 +25 3.24949 +26 3.81682 +27 3.6786 +28 5.26567 +29 5.75883 +30 4.40013 +31 4.8604 +32 3.88159 +33 3.62912 +34 6.09732 +35 6.23606 +36 6.81931 +37 3.98474 +38 5.09313 +39 7.92162 +40 5.91342 +41 5.89822 +42 7.79576 +43 3.26766 +44 6.40478 +45 3.30998 +46 5.75804 +47 4.44341 +48 5.56712 +49 7.92901 +50 7.32341 +51 4.11488 +52 7.27876 +53 4.46523 +54 4.41017 +55 4.24074 +56 5.18865 +57 3.67411 +58 3.93323 +59 6.27803 +60 5.7046 +61 5.43246 +62 6.62422 +63 6.87791 +64 4.8315 +65 4.41484 +66 3.44597 +67 4.80585 +68 4.76576 +69 5.09151 +70 3.90176 +71 3.98978 +72 7.05842 +73 5.79771 +74 5.72113 +75 5.39406 +76 8.36837 +77 6.57885 +78 3.81664 +79 5.04602 +80 5.13045 +81 4.17786 +82 4.12193 +83 5.498 +84 3.9477 +85 4.17729 +86 4.53085 +87 4.87674 +88 5.63865 +89 4.91132 +90 5.42233 +91 7.2101 +92 6.62552 +93 5.99626 +94 5.99827 +95 4.64279 +96 4.40763 +97 7.74874 +98 4.60244 +99 4.55322 +100 3.87632 +101 4.43066 +102 3.5908 +103 4.4961 +104 4.6942 +105 6.85876 +106 6.09827 +107 5.34771 +108 3.88554 +109 4.99917 +110 5.07909 +111 5.16529 +112 6.2445 +113 4.05386 +114 4.0937 +115 4.62717 +116 4.31849 +117 3.26285 +118 3.35407 +119 3.68025 +120 5.5668 +121 4.22251 +122 4.99967 +123 4.02172 +124 7.95474 +125 6.88951 +126 5.11647 +127 3.62751 +128 3.75947 +129 5.71937 +130 4.65378 +131 4.22097 +132 3.54665 +133 4.0164 +134 4.14403 +135 5.88228 +136 3.88365 +137 4.9027 +138 3.88649 +139 3.94684 +140 5.61741 +141 4.86852 +142 4.25794 +143 7.6941 +144 4.73617 +145 3.12373 +146 4.88928 +147 3.62576 +148 4.16485 +149 3.9426 +150 3.46852 +151 6.77747 +152 5.33702 +153 6.56503 +154 5.80932 +155 6.15413 +156 6.85355 +157 4.14906 +158 6.14933 +159 6.69641 +160 3.64734 +161 9.61926 +162 4.84044 +163 6.90865 +164 3.44809 +165 7.79131 +166 4.2801 +167 3.52051 +168 5.45391 +169 3.39718 +170 4.71838 +171 3.97902 +172 6.18658 +173 4.17284 +174 3.92603 +175 6.61929 +176 4.47741 +177 5.4168 +178 4.66072 +179 6.78272 +180 8.92575 +181 3.81346 +182 3.82779 +183 3.59616 +184 4.4729 +185 4.12509 +186 9.13405 +187 4.3469 +188 4.17304 +189 3.37722 +190 4.22285 +191 3.89981 +192 3.56114 +193 5.07249 +194 5.73119 +195 3.31977 +196 7.91262 +197 4.91172 +198 4.3087 +199 4.15402 +200 7.6821 +201 4.41955 +202 4.64581 +203 4.16326 +204 7.51723 +205 6.23256 +206 4.63327 +207 4.85318 +208 6.48807 +209 3.61821 +210 5.09043 +211 8.53276 +212 6.52094 +213 3.90421 +214 4.42601 +215 3.83625 +216 5.54714 +217 3.51603 +218 3.84227 +219 5.7805 +220 5.82631 +221 4.20829 +222 5.28021 +223 4.00498 +224 6.02503 +225 5.06898 +226 5.05237 +227 4.69681 +228 4.59421 +229 4.21961 +230 4.26009 +231 5.25661 +232 6.12045 +233 4.26478 +234 3.42011 +235 3.96254 +236 5.39782 +237 5.34452 +238 5.57074 +239 3.58786 +240 5.48832 +241 5.04805 +242 6.99507 +243 4.86669 +244 8.67723 +245 4.42583 +246 6.08779 +247 8.30081 +248 4.11458 +249 7.33372 +250 4.37632 +251 6.55974 +252 4.06411 +253 7.65217 +254 4.98446 +255 7.00166 +256 9.18261 +257 3.97417 +258 3.76504 +259 4.45173 +260 3.78705 +261 8.85178 +262 5.99438 +263 3.68369 +264 4.64732 +265 5.79147 +266 6.364 +267 5.03453 +268 4.96944 +269 4.75356 +270 3.20622 +271 4.24018 +272 4.41709 +273 4.21315 +274 4.38612 +275 6.51163 +276 5.01322 +277 5.46653 +278 3.97587 +279 6.44458 +280 4.97667 +281 5.55967 +282 5.85158 +283 5.0027 +284 3.48534 +285 6.58618 +286 4.80285 +287 5.94949 +288 4.82903 +289 7.5367 +290 5.70127 +291 7.09932 +292 5.78603 +293 5.97275 +294 3.8847 +295 7.18803 +296 4.24715 +297 6.96264 +298 7.0952 +299 4.63648 +300 6.55609 +301 5.16808 +302 5.24241 +303 3.54707 +304 4.3924 +305 4.0213 +306 4.62658 +307 4.81065 +308 4.56642 +309 6.50736 +310 4.75308 +311 3.8215 +312 3.41325 +313 4.08294 +314 4.91393 +315 5.30757 +316 7.02954 +317 5.24187 +318 4.13738 +319 6.58547 +320 3.70239 +321 3.67817 +322 4.58162 +323 5.24492 +324 4.86733 +325 4.91221 +326 4.2757 +327 5.39939 +328 4.61598 +329 8.42673 +330 6.14168 +331 4.57608 +332 3.81451 +333 4.29124 +334 4.12792 +335 5.02872 +336 5.23399 +337 3.38677 +338 4.50817 +339 5.28311 +340 5.64442 +341 4.71327 +342 6.09192 +343 4.17098 +344 7.35127 +345 5.55052 +346 8.62264 +347 7.92427 +348 4.62414 +349 5.61806 +350 5.34776 +351 6.86714 +352 4.07043 +353 3.76518 +354 3.52133 +355 4.0364 +356 4.23061 +357 5.51497 +358 5.34338 +359 5.2446 +360 3.66377 +361 3.61536 +362 4.93218 +363 5.91732 +364 3.99037 +365 6.86673 +366 4.57754 +367 4.54417 +368 3.49705 +369 3.68222 +370 4.05441 +371 3.28484 +372 3.86728 +373 6.47469 +374 3.8287 +375 4.21948 +376 6.50072 +377 5.2599 +378 5.46621 +379 3.90163 +380 8.20664 +381 5.20216 +382 5.3226 +383 4.03878 +384 8.93219 +385 6.79859 +386 5.0444 +387 4.38992 +388 6.97679 +389 3.69486 +390 3.64051 +391 3.67985 +392 6.23422 +393 3.30838 +394 7.50667 +395 3.94216 +396 6.5134 +397 8.60865 +398 4.39139 +399 3.46463 +400 3.90001 +401 4.26802 +402 3.71403 +403 3.59913 +404 3.15595 +405 4.92885 +406 9.80662 +407 3.63884 +408 3.80748 +409 5.15094 +410 6.35325 +411 4.20196 +412 5.86833 +413 5.91247 +414 3.313 +415 3.37645 +416 4.89339 +417 5.19552 +418 6.53485 +419 7.98558 +420 3.6091 +421 4.05488 +422 4.29978 +423 4.68265 +424 8.03386 +425 5.59842 +426 4.70185 +427 3.61697 +428 5.69205 +429 7.16982 +430 4.13106 +431 3.56492 +432 4.22082 +433 4.55629 +434 4.58142 +435 5.53457 +436 6.93426 +437 4.80377 +438 3.84526 +439 3.94317 +440 3.45505 +441 5.16289 +442 3.25289 +443 3.95152 +444 5.40892 +445 6.95209 +446 4.15315 +447 5.02186 +448 4.01812 +449 3.96462 +450 7.14857 +451 4.97123 +452 4.79327 +453 4.80934 +454 7.58936 +455 4.07601 +456 4.83387 +457 4.20561 +458 4.19693 +459 4.28828 +460 6.64926 +461 6.10328 +462 5.14523 +463 3.29956 +464 7.82612 +465 6.51338 +466 5.14228 +467 6.36966 +468 4.00039 +469 5.25401 +470 4.90217 +471 3.91685 +472 4.04775 +473 3.71452 +474 4.00893 +475 6.15397 +476 4.73995 +477 4.49103 +478 6.01817 +479 4.51129 +480 4.45673 +481 4.53029 +482 4.39765 +483 4.84946 +484 4.41482 +485 5.22789 +486 4.83751 +487 4.52841 +488 4.37907 +489 4.53931 +490 3.94812 +491 5.60107 +492 7.82411 +493 6.10887 +494 3.61105 +495 6.22222 +496 5.87689 +497 4.37764 +498 5.74756 +499 5.41576 +500 3.94004 +501 5.49027 +502 4.62278 +503 5.90077 +504 3.72543 +505 8.58284 +506 9.99379 +507 3.93429 +508 7.00354 +509 3.34162 +510 6.26251 +511 4.5708 +512 4.61934 +513 6.10199 +514 7.60203 +515 3.49142 +516 6.17078 +517 5.25425 +518 6.30042 +519 5.72046 +520 4.47283 +521 4.83221 +522 4.41013 +523 5.97733 +524 3.99931 +525 4.76894 +526 3.74452 +527 6.2368 +528 4.09343 +529 6.26363 +530 6.83661 +531 3.96425 +532 3.43579 +533 5.77657 +534 5.34581 +535 4.68041 +536 4.37814 +537 5.99737 +538 5.3648 +539 5.4205 +540 4.22935 +541 5.82056 +542 3.98684 +543 3.28936 +544 4.1958 +545 4.33791 +546 4.85201 +547 5.22988 +548 6.51603 +549 4.38544 +550 4.03691 +551 4.28065 +552 7.54771 +553 5.3477 +554 3.98013 +555 3.65612 +556 3.6305 +557 4.96827 +558 7.0639 +559 5.12306 +560 5.26116 +561 3.98468 +562 4.06433 +563 4.43174 +564 9.65465 +565 4.48661 +566 7.06711 +567 6.01908 +568 5.78751 +569 6.07332 +570 8.58829 +571 7.11434 +572 3.46196 +573 5.46102 +574 6.3086 +575 5.34819 +576 6.91082 +577 4.47437 +578 7.81942 +579 6.82906 +580 4.72318 +581 4.06215 +582 9.60519 +583 5.3436 +584 4.7691 +585 4.475 +586 5.84693 +587 5.8161 +588 4.01326 +589 8.52049 +590 6.06203 +591 3.94 +592 6.42148 +593 6.28834 +594 4.88767 +595 7.62703 +596 7.56987 +597 5.54109 +598 4.11926 +599 6.37613 +600 4.92981 +601 4.80206 +602 3.26213 +603 6.37042 +604 5.17572 +605 3.76555 +606 5.26092 +607 4.19725 +608 3.19057 +609 5.88572 +610 5.22575 +611 3.782 +612 4.38116 +613 8.53952 +614 4.30787 +615 4.10562 +616 7.62857 +617 5.65392 +618 5.96086 +619 4.91053 +620 6.14863 +621 5.91276 +622 4.27409 +623 5.55369 +624 4.8645 +625 4.77293 +626 3.55957 +627 4.11882 +628 3.68402 +629 6.55336 +630 5.93665 +631 6.29134 +632 5.06148 +633 6.32722 +634 3.56814 +635 4.97852 +636 5.319 +637 7.67988 +638 4.9724 +639 3.58948 +640 3.2273 +641 4.94275 +642 6.132 +643 4.23477 +644 3.8824 +645 6.47761 +646 5.83872 +647 6.52367 +648 9.09261 +649 4.02275 +650 4.5423 +651 3.77518 +652 9.34733 +653 4.29857 +654 3.53165 +655 3.69875 +656 8.91855 +657 8.27777 +658 4.2927 +659 5.44146 +660 4.88306 +661 4.61662 +662 4.66585 +663 4.08773 +664 5.47614 +665 4.82537 +666 5.34588 +667 5.09433 +668 4.74203 +669 4.80349 +670 5.17033 +671 5.55982 +672 5.85245 +673 8.50255 +674 5.05679 +675 8.2833 +676 4.20019 +677 6.65706 +678 5.50201 +679 3.83497 +680 8.04853 +681 3.98407 +682 4.14575 +683 4.40359 +684 3.83137 +685 7.5115 +686 4.55691 +687 5.02113 +688 4.10109 +689 3.2165 +690 6.76792 +691 7.39527 +692 5.09019 +693 4.66208 +694 4.89628 +695 3.82454 +696 7.89338 +697 4.34543 +698 4.53367 +699 4.2245 +700 7.97378 +701 5.36364 +702 5.48083 +703 5.18437 +704 7.54515 +705 8.01303 +706 6.9711 +707 5.10957 +708 4.65648 +709 4.17603 +710 3.95182 +711 4.30453 +712 4.83791 +713 5.75603 +714 6.26297 +715 4.26312 +716 4.92191 +717 6.49723 +718 5.39117 +719 7.63936 +720 3.8902 +721 5.26165 +722 3.56636 +723 5.80111 +724 8.11139 +725 6.99287 +726 6.0905 +727 4.48145 +728 6.29626 +729 6.41609 +730 4.82834 +731 4.30295 +732 5.95249 +733 9.1162 +734 7.17952 +735 4.41636 +736 7.00516 +737 5.38428 +738 4.57018 +739 5.16323 +740 6.21328 +741 3.84546 +742 8.92755 +743 4.95277 +744 5.60229 +745 4.74588 +746 4.39131 +747 3.53583 +748 4.71464 +749 3.85774 +750 4.32924 +751 4.21807 +752 5.56949 +753 3.92575 +754 4.08047 +755 4.19341 +756 5.43269 +757 5.08675 +758 7.55608 +759 4.60229 +760 5.26588 +761 6.53396 +762 6.09301 +763 8.49182 +764 3.65278 +765 3.7977 +766 4.72003 +767 5.07267 +768 5.39706 +769 5.74691 +770 7.17011 +771 4.60288 +772 6.53685 +773 5.03197 +774 4.75913 +775 5.21044 +776 8.20214 +777 5.1994 +778 5.72262 +779 5.56165 +780 5.11548 +781 4.91619 +782 4.4872 +783 5.68936 +784 4.47124 +785 5.13239 +786 3.56721 +787 6.21762 +788 7.03673 +789 4.75488 +790 6.58105 +791 6.02163 +792 4.0573 +793 5.61253 +794 4.57518 +795 6.37637 +796 4.44356 +797 4.71151 +798 7.569 +799 4.14096 +800 5.59666 +801 4.97895 +802 3.58641 +803 3.31542 +804 5.39692 +805 4.83649 +806 3.97031 +807 5.44832 +808 4.02433 +809 3.60805 +810 5.34786 +811 3.58587 +812 6.69862 +813 3.32895 +814 4.09119 +815 4.58371 +816 3.80674 +817 6.44114 +818 6.223 +819 4.0441 +820 4.80123 +821 4.30222 +822 6.44328 +823 5.35506 +824 6.92359 +825 3.89947 +826 6.49231 +827 4.93294 +828 4.30558 +829 6.36489 +830 6.66548 +831 4.33778 +832 4.17984 +833 5.47755 +834 6.30491 +835 4.8866 +836 3.97457 +837 5.46085 +838 9.49042 +839 5.90533 +840 4.86468 +841 6.77968 +842 4.50722 +843 6.47377 +844 6.71684 +845 7.28311 +846 4.96895 +847 4.62845 +848 4.76509 +849 4.94072 +850 6.06047 +851 5.03461 +852 4.02971 +853 6.54434 +854 6.22769 +855 4.93337 +856 3.68803 +857 3.53863 +858 3.91408 +859 5.65137 +860 7.37176 +861 4.59552 +862 6.93334 +863 3.44661 +864 6.33348 +865 5.02479 +866 5.35196 +867 4.49256 +868 4.90908 +869 5.13244 +870 6.53011 +871 6.74559 +872 6.30754 +873 4.22522 +874 5.22566 +875 4.48669 +876 6.19697 +877 5.32891 +878 5.90513 +879 5.26841 +880 4.69307 +881 6.53259 +882 5.37303 +883 4.84613 +884 6.84862 +885 8.57067 +886 4.51242 +887 4.09543 +888 3.96732 +889 3.54212 +890 7.13459 +891 3.96056 +892 3.53356 +893 7.88643 +894 3.71017 +895 4.50089 +896 6.13237 +897 9.12911 +898 5.99732 +899 4.20221 +900 5.07845 +901 7.39265 +902 3.4358 +903 6.92631 +904 6.19262 +905 8.37263 +906 3.90019 +907 5.27365 +908 8.43827 +909 4.30468 +910 7.89174 +911 4.55601 +912 5.99339 +913 3.9157 +914 6.4819 +915 5.12264 +916 4.56214 +917 4.68284 +918 3.62525 +919 5.50492 +920 3.3911 +921 5.44747 +922 5.1212 +923 3.91631 +924 4.09731 +925 3.90953 +926 3.24567 +927 3.84614 +928 3.16043 +929 5.57228 +930 5.27177 +931 4.70165 +932 6.21956 +933 6.82471 +934 4.75076 +935 5.36529 +936 7.32308 +937 5.56332 +938 4.4607 +939 4.55218 +940 4.41271 +941 4.16343 +942 3.60628 +943 5.64808 +944 5.0414 +945 4.07399 +946 8.06578 +947 5.13059 +948 3.32765 +949 6.87378 +950 6.8715 +951 5.34151 +952 7.4087 +953 4.97386 +954 4.34552 +955 4.26796 +956 4.19602 +957 3.42375 +958 5.85754 +959 5.66926 +960 8.16791 +961 5.85989 +962 5.27303 +963 4.04843 +964 3.73455 +965 6.69521 +966 3.19527 +967 5.41381 +968 4.9373 +969 3.34371 +970 5.277 +971 5.14515 +972 4.27359 +973 3.45159 +974 4.18209 +975 3.97173 +976 6.6748 +977 5.48345 +978 5.03449 +979 6.2847 +980 4.28563 +981 4.42304 +982 8.30151 +983 8.10918 +984 5.2181 +985 6.07928 +986 7.4987 +987 3.86094 +988 7.79415 +989 4.1437 +990 4.22013 +991 4.84238 +992 4.18954 +993 4.63546 +994 5.03533 +995 5.68754 +996 3.66053 +997 4.99215 +998 3.9023 +999 6.64228 +1000 3.66927 +1001 7.59005 +1002 7.84943 +1003 6.12621 +1004 4.28124 +1005 5.25678 +1006 4.49358 +1007 3.83982 +1008 4.1934 +1009 4.15133 +1010 5.9278 +1011 6.99563 +1012 5.9841 +1013 8.90109 +1014 7.652 +1015 7.06981 +1016 4.2989 +1017 4.43713 +1018 3.94864 +1019 5.25543 +1020 5.67571 +1021 4.55211 +1022 5.55705 +1023 4.35115 +1024 3.53053 +1025 4.95254 +1026 5.0626 +1027 5.91199 +1028 3.64351 +1029 4.37971 +1030 6.08977 +1031 8.17508 +1032 9.08688 +1033 6.27308 +1034 5.95361 +1035 5.76509 +1036 4.96722 +1037 5.54433 +1038 4.46812 +1039 5.33303 +1040 6.1708 +1041 6.72636 +1042 5.29678 +1043 4.55251 +1044 8.94976 +1045 3.51383 +1046 9.65923 +1047 5.82992 +1048 4.65022 +1049 4.9202 +1050 5.80657 +1051 3.98189 +1052 5.41173 +1053 4.62405 +1054 3.74779 +1055 3.72462 +1056 4.19243 +1057 8.98073 +1058 5.19122 +1059 4.03261 +1060 3.37577 +1061 5.38447 +1062 7.73223 +1063 8.13835 +1064 4.25916 +1065 4.74505 +1066 7.41008 +1067 7.34217 +1068 4.67887 +1069 7.30568 +1070 4.68001 +1071 4.1343 +1072 4.30236 +1073 4.91304 +1074 3.81816 +1075 4.33604 +1076 7.30661 +1077 3.71466 +1078 5.48295 +1079 5.02695 +1080 5.64749 +1081 4.97985 +1082 5.0635 +1083 4.18982 +1084 6.63653 +1085 6.50817 +1086 4.06997 +1087 4.6217 +1088 3.9456 +1089 5.86381 +1090 4.34958 +1091 4.72955 +1092 7.68562 +1093 4.76352 +1094 4.38867 +1095 7.24025 +1096 8.56583 +1097 7.12327 +1098 7.63126 +1099 4.98995 +1100 5.51299 +1101 6.22274 +1102 8.55485 +1103 4.67541 +1104 5.56093 +1105 4.11592 +1106 5.39012 +1107 4.91738 +1108 4.55802 +1109 9.81191 +1110 9.03824 +1111 4.91096 +1112 5.68686 +1113 5.43295 +1114 4.5376 +1115 7.76145 +1116 6.56722 +1117 5.56414 +1118 6.48512 +1119 7.08636 +1120 4.86379 +1121 5.06374 +1122 4.43781 +1123 6.37562 +1124 8.00607 +1125 5.72785 +1126 7.44421 +1127 8.55665 +1128 5.86133 +1129 9.30702 +1130 5.39706 +1131 9.72751 +1132 3.48947 +1133 4.01753 +1134 6.24749 +1135 5.18517 +1136 3.7291 +1137 5.12041 +1138 5.72019 +1139 8.40329 +1140 4.29092 +1141 6.32703 +1142 4.81643 +1143 6.2805 +1144 8.28778 +1145 6.11067 +1146 4.67958 +1147 6.84822 +1148 6.91117 +1149 8.73063 +1150 5.19026 +1151 8.76106 +1152 7.46817 +1153 4.01789 +1154 4.79286 +1155 4.32607 +1156 8.23324 +1157 4.8066 +1158 6.2838 +1159 6.4227 +1160 9.33195 +1161 4.68307 +1162 6.92146 +1163 6.30771 +1164 7.57291 +1165 7.22122 +1166 6.39772 +1167 5.60827 +1168 3.81708 +1169 3.25156 +1170 8.08526 +1171 7.77888 +1172 4.56788 +1173 8.09687 +1174 3.49101 +1175 4.88315 +1176 9.9666 +1177 5.09136 +1178 4.89489 +1179 8.84418 +1180 4.97986 +1181 5.33513 +1182 5.84621 +1183 3.85303 +1184 4.81127 +1185 7.16765 +1186 5.06141 +1187 7.20188 +1188 4.7328 +1189 5.06946 +1190 3.66104 +1191 4.29874 +1192 3.89884 +1193 6.80851 +1194 5.53224 +1195 7.4339 +1196 5.48488 +1197 8.32916 +1198 5.44496 +1199 5.953 +1200 7.10064 +1201 4.28803 +1202 5.27418 +1203 3.79067 +1204 3.44724 +1205 4.17183 +1206 7.19842 +1207 4.32375 +1208 3.51299 +1209 7.615 +1210 5.69386 +1211 6.73423 +1212 4.51568 +1213 6.08616 +1214 5.21758 +1215 8.14411 +1216 4.06477 +1217 5.22976 +1218 5.07475 +1219 5.92439 +1220 4.9689 +1221 5.09276 +1222 7.43835 +1223 6.71407 +1224 7.02283 +1225 6.5295 +1226 4.40292 +1227 5.83422 +1228 3.70634 +1229 3.52758 +1230 6.0864 +1231 4.79487 +1232 5.2648 +1233 6.60461 +1234 4.95882 +1235 9.41937 +1236 5.13095 +1237 5.28013 +1238 5.44854 +1239 7.71878 +1240 5.56885 +1241 8.76006 +1242 4.56393 +1243 5.90289 +1244 6.17245 +1245 5.47762 +1246 6.85481 +1247 3.17205 +1248 4.86204 +1249 4.43452 +1250 6.97671 +1251 5.3337 +1252 5.43708 +1253 5.01141 +1254 7.23168 +1255 3.70348 +1256 4.66871 +1257 8.66635 +1258 7.63642 +1259 6.58896 +1260 5.63525 +1261 5.18847 +1262 4.60493 +1263 8.295 +1264 7.64526 +1265 3.59029 +1266 8.30829 +1267 5.61988 +1268 4.40627 +1269 8.59727 +1270 7.237 +1271 5.90024 +1272 4.03286 +1273 4.8429 +1274 7.10562 +1275 6.50655 +1276 4.64487 +1277 4.69878 +1278 7.97432 +1279 4.02501 +1280 5.38605 +1281 4.92341 +1282 5.07646 +1283 3.75685 +1284 5.31243 +1285 5.7707 +1286 5.68964 +1287 5.96062 +1288 7.85077 +1289 8.21576 +1290 6.68323 +1291 4.30884 +1292 4.784 +1293 5.21908 +1294 4.82005 +1295 4.40245 +1296 4.02024 +1297 3.62885 +1298 3.78701 +1299 3.55008 +1300 4.66264 +1301 5.58137 +1302 4.33701 +1303 4.93396 +1304 3.52374 +1305 7.13144 +1306 5.36387 +1307 8.97625 +1308 5.18498 +1309 9.05048 +1310 8.19838 +1311 4.42885 +1312 8.34232 +1313 3.94079 +1314 4.41342 +1315 7.69708 +1316 4.03687 +1317 4.88914 +1318 4.97387 +1319 5.60074 +1320 3.64249 +1321 3.99359 +1322 5.05358 +1323 7.22987 +1324 9.02307 +1325 3.92924 +1326 5.90228 +1327 6.68582 +1328 9.38571 +1329 4.23719 +1330 3.91918 +1331 6.00412 +1332 8.07751 +1333 4.80956 +1334 5.50254 +1335 9.28165 +1336 4.67539 +1337 4.8626 +1338 6.60907 +1339 6.82969 +1340 5.02785 +1341 4.99683 +1342 7.89183 +1343 9.24249 +1344 5.19206 +1345 4.25973 +1346 5.32035 +1347 4.13126 +1348 5.9532 +1349 6.48769 +1350 3.89076 +1351 5.66956 +1352 7.52047 +1353 5.81182 +1354 7.64656 +1355 5.39628 +1356 5.38481 +1357 4.57187 +1358 7.85941 +1359 3.19563 +1360 4.16723 +1361 7.58062 +1362 5.43379 +1363 4.5491 +1364 9.55822 +1365 5.41463 +1366 3.93709 +1367 5.58151 +1368 7.63004 +1369 7.19653 +1370 6.21067 +1371 4.16437 +1372 7.03794 +1373 6.03681 +1374 7.32543 +1375 8.75148 +1376 9.85852 +1377 5.51133 +1378 8.69481 +1379 5.56414 +1380 6.99819 +1381 3.55529 +1382 5.3928 +1383 4.84586 +1384 7.9864 +1385 6.53059 +1386 4.99042 +1387 4.16435 +1388 6.80177 +1389 5.45811 +1390 5.63078 +1391 3.96717 +1392 3.86136 +1393 3.20475 +1394 8.36851 +1395 5.32051 +1396 4.09927 +1397 4.30378 +1398 6.53894 +1399 9.57378 +1400 6.55006 +1401 6.34936 +1402 4.66909 +1403 4.92672 +1404 6.29711 +1405 6.13071 +1406 7.07983 +1407 3.38745 +1408 6.19644 +1409 3.70599 +1410 8.72514 +1411 5.01474 +1412 6.35499 +1413 8.51238 +1414 6.1006 +1415 8.31744 +1416 8.69373 +1417 5.3837 +1418 3.29415 +1419 3.17415 +1420 4.65337 +1421 3.77393 +1422 3.8875 +1423 7.11242 +1424 4.79596 +1425 4.074 +1426 4.91429 +1427 5.40041 +1428 4.50152 +1429 6.82147 +1430 7.03258 +1431 9.84567 +1432 5.28303 +1433 3.28496 +1434 5.3585 +1435 5.80604 +1436 6.24381 +1437 3.80452 +1438 8.7948 +1439 6.69635 +1440 5.38362 +1441 8.19043 +1442 6.65785 +1443 5.14952 +1444 8.66002 +1445 6.98012 +1446 5.82976 +1447 4.7057 +1448 4.19243 +1449 4.46766 +1450 4.94058 +1451 8.7967 +1452 5.51495 +1453 4.0043 +1454 5.16481 +1455 6.42095 +1456 6.01744 +1457 3.71544 +1458 5.73042 +1459 8.12425 +1460 3.95837 +1461 7.51813 +1462 9.24805 +1463 7.61923 +1464 4.43411 +1465 3.83737 +1466 3.95716 +1467 7.15998 +1468 5.65757 +1469 3.42947 +1470 7.66079 +1471 5.68317 +1472 4.17696 +1473 3.43991 +1474 4.08425 +1475 6.28225 +1476 5.03584 +1477 5.6927 +1478 4.82533 +1479 7.60644 +1480 3.80633 +1481 7.85466 +1482 4.0313 +1483 5.53088 +1484 4.79008 +1485 6.91984 +1486 7.05097 +1487 5.06758 +1488 5.28323 +1489 3.97634 +1490 7.07548 +1491 6.99741 +1492 5.39725 +1493 3.70965 +1494 5.20786 +1495 3.35697 +1496 8.30445 +1497 6.24412 +1498 5.02406 +1499 4.3192 +1500 3.75267 +1501 3.75419 +1502 6.70461 +1503 7.29339 +1504 7.25608 +1505 4.67025 +1506 7.00533 +1507 4.95845 +1508 5.9428 +1509 8.22798 +1510 6.09413 +1511 6.69181 +1512 4.68312 +1513 8.54909 +1514 9.17576 +1515 4.67904 +1516 5.70206 +1517 3.82361 +1518 4.83649 +1519 4.49647 +1520 6.62776 +1521 3.87563 +1522 3.82749 +1523 7.136 +1524 5.46372 +1525 7.49927 +1526 4.77056 +1527 6.99557 +1528 5.41681 +1529 5.67049 +1530 9.09783 +1531 6.2033 +1532 5.7676 +1533 6.10859 +1534 5.64874 +1535 4.25459 +1536 4.24224 +1537 7.54998 +1538 4.6898 +1539 3.65217 +1540 6.77849 +1541 7.38216 +1542 5.01269 +1543 9.63731 +1544 5.93312 +1545 6.67582 +1546 4.31103 +1547 7.11233 +1548 9.36116 +1549 5.26081 +1550 5.69302 +1551 3.48767 +1552 6.63839 +1553 6.58539 +1554 7.28664 +1555 3.81367 +1556 4.57632 +1557 5.76642 +1558 5.47675 +1559 4.10006 +1560 7.47012 +1561 4.71169 +1562 7.33109 +1563 3.61097 +1564 7.2049 +1565 5.17177 +1566 5.69784 +1567 5.66136 +1568 5.26364 +1569 5.80611 +1570 6.17947 +1571 7.04854 +1572 8.77365 +1573 4.85623 +1574 3.77604 +1575 4.3199 +1576 5.59875 +1577 7.20581 +1578 8.22279 +1579 6.75557 +1580 6.15071 +1581 8.40391 +1582 5.84813 +1583 6.71808 +1584 9.4805 +1585 5.78575 +1586 5.53995 +1587 6.22247 +1588 6.41044 +1589 4.20686 +1590 5.13741 +1591 9.43675 +1592 4.7142 +1593 3.98455 +1594 7.70331 +1595 5.7983 +1596 5.38736 +1597 6.27297 +1598 5.693 +1599 7.78512 +1600 9.5604 +1601 3.88507 +1602 5.01882 +1603 7.63484 +1604 5.06804 +1605 4.18197 +1606 4.43359 +1607 4.34535 +1608 4.02395 +1609 7.2371 +1610 8.47037 +1611 4.49746 +1612 8.23039 +1613 4.43065 +1614 4.82179 +1615 7.15842 +1616 4.60424 +1617 4.60142 +1618 4.98153 +1619 4.82699 +1620 6.48302 +1621 5.81494 +1622 9.77863 +1623 9.18164 +1624 8.97711 +1625 6.39388 +1626 4.3432 +1627 8.33951 +1628 5.09327 +1629 5.99447 +1630 4.3455 +1631 6.29698 +1632 3.33295 +1633 6.59657 +1634 6.95084 +1635 3.19532 +1636 5.517 +1637 5.79544 +1638 5.11606 +1639 5.09728 +1640 6.96594 +1641 4.43697 +1642 8.62959 +1643 6.33994 +1644 4.6679 +1645 6.9788 +1646 4.62802 +1647 9.58879 +1648 4.3363 +1649 5.16264 +1650 7.16104 +1651 5.92186 +1652 7.45343 +1653 3.24729 +1654 9.37208 +$EndElementData diff --git a/test/user/testdata/shark_22_ascii_missing_num_nodes.msh b/test/user/testdata/shark_22_ascii_missing_num_nodes.msh new file mode 100644 index 00000000..cb68a680 --- /dev/null +++ b/test/user/testdata/shark_22_ascii_missing_num_nodes.msh @@ -0,0 +1,3978 @@ +$MeshFormat +2.2 0 8 +$EndMeshFormat +$Nodes +1 -0.0733436 0.0816748 0.056402 +2 -0.0729126 0.0537921 0.00170478 +3 -0.072634 0.0799069 0.0578949 +4 -0.0715817 0.0520377 0.00292576 +5 -0.0701949 0.0802569 0.0450431 +6 -0.0687698 0.060971 0.00326551 +7 -0.06778 0.060358 0.00473741 +8 -0.0672796 0.0809249 0.0425553 +9 -0.0658074 0.0806443 0.0552302 +10 -0.064933 0.0788176 0.0453762 +11 -0.0636555 0.0610198 0.00141989 +12 -0.0636111 0.0566004 -0.000556663 +13 -0.0636791 0.0819076 0.0524468 +14 -0.0623445 0.0580268 0.00335683 +15 -0.0624856 0.0671058 0.00581638 +16 -0.0601398 0.0781111 0.0317589 +17 -0.0599443 0.0685632 0.00992449 +18 -0.0592787 0.0571239 0.00105116 +19 -0.0587906 0.0719999 0.0117948 +20 -0.0575605 0.0730663 0.016213 +21 -0.057624 0.0811803 0.0403639 +22 -0.0572339 0.0769387 0.0223219 +23 -0.0559974 0.0749629 0.0235691 +24 -0.0542321 0.0763209 0.0344665 +25 -0.0540672 0.0649483 0.00821813 +26 -0.0541685 0.0661135 0.00437935 +27 -0.0532966 0.0805356 0.0466758 +28 -0.0517252 0.0761185 0.0183218 +29 -0.0505257 0.068877 0.0152572 +30 -0.0503803 0.0772638 0.0406423 +31 -0.0472855 0.0641041 0.00381053 +32 -0.0469016 0.0648796 0.00821733 +33 -0.0474599 0.0727268 0.0265623 +34 -0.0464733 0.070912 0.0103373 +35 -0.0444756 0.0755674 0.0221683 +36 -0.0440208 0.0774313 0.0371107 +37 -0.0434135 0.0685101 0.0213943 +38 -0.0425401 0.0668787 0.0159114 +39 -0.0405353 0.0730163 0.0309862 +40 -0.0386417 0.073548 0.0160682 +41 -0.037401 0.0664899 0.0122191 +42 -0.0358693 0.0689445 0.0243885 +43 -0.0351058 0.0687771 0.0124837 +44 -0.0333614 0.071165 0.0238503 +45 -0.0325564 0.0696271 0.024504 +46 -0.032455 0.0625178 0.0200737 +47 -0.0305469 0.0729973 0.0173921 +48 -0.0276941 0.0652386 0.0128238 +49 -0.0272717 0.0628782 0.0141328 +50 -0.0263428 0.00735496 0.00505748 +51 -0.0256055 0.00658056 0.00327552 +52 -0.0252856 0.0610141 0.0227762 +53 -0.0250237 -0.00678856 0.00359213 +54 -0.0242889 -0.00589458 0.00589675 +55 -0.0216872 0.0639735 0.0255561 +56 -0.0215721 -0.0119744 0.00619585 +57 -0.0195136 0.0542304 0.0216195 +58 -0.0168343 0.0649534 0.0236547 +59 -0.0161373 -0.00420129 0.00881529 +60 -0.0148726 0.0585475 0.0106707 +61 -0.0140647 0.0517836 0.0159197 +62 -0.0142986 0.0543801 0.0051496 +63 -0.0139611 -0.0178642 0.00651265 +64 -0.0139803 0.0554055 0.0115694 +65 -0.0124373 0.0606817 0.0122622 +66 -0.0127423 0.0580719 0.0285553 +67 -0.0127412 -0.0704232 0.0234664 +68 -0.0126173 -0.0801905 0.022154 +69 -0.0125269 0.0592002 0.0346418 +70 -0.0122498 -0.080596 0.0191154 +71 -0.0121442 -0.0691943 0.0191352 +72 -0.0123618 0.0658492 0.0197519 +73 -0.0121018 -0.063334 0.0245151 +74 -0.0118539 0.0462485 0.0243954 +75 -0.0111067 0.0637388 0.0161162 +76 -0.0110042 -0.0624802 0.0276395 +77 -0.0109072 0.046219 0.0183571 +78 -0.0107037 -0.000325242 0.00950432 +79 -0.010183 -0.0121386 0.00674337 +80 -0.00977442 -0.0638147 0.0162637 +81 -0.0097669 -0.0699334 0.0156591 +82 -0.00942656 -0.0836042 0.0182705 +83 -0.009321 -0.0852334 0.0216727 +84 -0.00803502 0.0401179 0.0263407 +85 -0.00857808 -0.0579335 0.0163943 +86 -0.00793158 -0.0190616 0.0121625 +87 -0.00782675 0.0573514 0.028038 +88 -0.00773028 -0.0620746 0.0302044 +89 -0.00764665 0.0537773 0.00961295 +90 -0.00721562 -0.0507362 0.0224357 +91 -0.00717408 -0.0528249 0.0179333 +92 -0.00651588 -0.00739691 0.013024 +93 -0.00691116 -0.00014073 0.00823716 +94 -0.00661131 0.044183 0.0123 +95 -0.00658663 0.0535365 0.0326225 +96 -0.00630954 -0.0850657 0.0194796 +97 -0.00616497 -0.0797841 0.0261073 +98 -0.00582999 -0.0494502 0.0287705 +99 -0.00563359 0.0476479 0.00934546 +100 -0.00506609 -0.0425596 0.0250833 +101 -0.00453974 -0.0405694 0.0173853 +102 -0.00447266 0.0319291 0.0205877 +103 -0.00434886 0.0267225 0.00648417 +104 -0.00418386 0.0253438 0.00842196 +105 -0.0041733 -0.0606038 0.0122716 +106 -0.00385183 0.0479538 0.00869149 +107 -0.00333705 0.051389 0.031593 +108 -0.00333565 -0.0693881 0.0119551 +109 -0.00333748 -0.0650683 0.0110291 +110 -0.00292457 0.0475597 0.0319288 +111 -0.00280471 -0.0353375 0.0238411 +112 -0.00273019 -0.0493159 0.0135756 +113 -0.00255346 -0.0452657 0.0126112 +114 -0.00249178 -0.0598565 0.010934 +115 -0.00247351 -0.0533955 0.0149632 +116 -0.00280465 0.0288144 0.0300227 +117 -0.00225175 -0.030519 0.0236922 +118 -0.00205777 -0.0595101 0.00715068 +119 -0.0018581 -0.0627033 0.0116048 +120 -0.00150112 -0.0384203 0.0313885 +121 -0.00143547 -0.0337232 0.0176227 +122 -0.00136747 -0.062725 0.0150152 +123 -0.000884775 -0.0587825 0.0143119 +124 -0.000624659 -0.0247814 0.0257906 +125 -0.000489974 0.0225414 0.0188523 +126 -6.05566e-05 0.0171338 0.0234086 +127 0.00150381 0.0360475 0.00675461 +128 0.000282178 -0.0241462 0.0174969 +129 0.000347869 -0.0675237 0.0324883 +130 0.000429839 -0.0422219 0.0349169 +131 0.00028168 -0.0273698 0.0312235 +132 0.000952705 -0.0267391 0.0143612 +133 0.00105244 0.0186951 0.00689988 +134 0.0011109 -0.0779453 0.014663 +135 0.00137887 0.00842564 0.0258445 +136 0.00107238 -0.0462225 0.00980545 +137 0.00158113 -0.0561697 0.005809 +138 0.00165921 -0.0142314 0.0114909 +139 0.00169065 -0.00330978 0.027848 +140 0.0017282 0.0264299 0.00972258 +141 0.00196109 -0.062067 0.0125082 +142 0.00198494 -0.0249792 0.0122768 +143 0.00206797 -0.0322322 0.0125632 +144 0.00219287 -0.00991015 0.0199027 +145 0.00223228 -0.065619 0.00972103 +146 0.00226787 -0.06664 0.0139131 +147 0.00233081 0.00970751 0.0349608 +148 0.0023033 -0.0550711 0.0357611 +149 0.00284591 -0.0695874 0.0109337 +150 0.00313658 0.0123831 0.0152878 +151 0.00325266 -0.000639164 0.0164744 +152 0.00354678 -0.0651674 0.00553443 +153 0.00434877 0.0392681 0.00656793 +154 0.0034004 -0.0624097 0.0143354 +155 0.00410027 0.052311 0.0146156 +156 0.00425687 -0.0110681 0.0377954 +157 0.0043501 -0.0020508 0.015115 +158 0.00444422 -0.0785667 0.0168482 +159 0.00471578 -0.00872746 0.0133588 +160 0.00486541 0.0192794 0.0102326 +161 0.00475235 0.0259901 0.00777948 +162 0.00497525 -0.0797755 0.0244877 +163 0.0052286 0.0545416 0.0234287 +164 0.00513856 -0.0361953 0.00904286 +165 0.00543656 -0.016404 0.0117933 +166 0.00521097 0.0361763 0.0357574 +167 0.00563068 0.0458779 0.0101474 +168 0.00602624 -0.0598053 0.00448538 +169 0.00669265 -0.0730234 0.0300997 +170 0.00671975 -0.0647944 0.0149968 +171 0.00743572 0.0219428 0.00498754 +172 0.00806977 -0.0676622 0.0106835 +173 0.00858002 0.0185363 0.00804532 +174 0.00900922 -0.0527441 0.0382868 +175 0.00967438 -0.0310472 0.0412759 +176 0.00969027 -0.0470756 0.00574739 +177 0.00982547 -0.0777201 0.0238208 +178 0.010337 -0.0646559 0.00738197 +179 0.0103691 -0.0715108 0.0301524 +180 0.0108524 -0.0651923 0.0107074 +181 0.0112352 0.0223598 0.00496048 +182 0.0115762 0.0360388 0.034027 +183 0.011811 0.0150563 0.0411225 +184 0.0119389 -0.0710873 0.0142927 +185 0.011481 0.000850754 0.00890493 +186 0.0122581 0.0177891 0.00726338 +187 0.0126044 0.0285097 0.0071727 +188 0.0126077 -0.0410848 0.00487059 +189 0.01325 0.0245576 0.00385279 +190 0.0133342 -0.0301914 0.00695184 +191 0.0134526 -0.00467313 0.044297 +192 0.0140263 0.0415073 0.0128325 +193 0.0139319 -0.0627506 0.0126489 +194 0.0144402 0.0213321 0.0408733 +195 0.0145153 -0.0120242 0.00709154 +196 0.0145254 0.0314471 0.00762861 +197 0.0143606 -0.0539791 0.00638859 +198 0.0153705 -0.0588177 0.00913193 +199 0.0158483 0.0424843 0.0267153 +200 0.0161677 0.0082135 0.0752128 +201 0.0160709 -0.0693691 0.0267104 +202 0.0163112 0.021127 0.00658374 +203 0.0163956 0.0418119 0.0180916 +204 0.0166653 0.00513625 0.0449469 +205 0.0171438 -0.00939438 0.0462661 +206 0.0174416 -0.0497054 0.0373642 +207 0.0174198 -0.0656937 0.0159871 +208 0.0177387 0.0346114 0.0053358 +209 0.0178439 0.0247259 0.00729322 +210 0.018247 0.0346901 0.00258831 +211 0.0182074 -0.0318958 0.0424624 +212 0.0183988 -0.00142899 0.0496692 +213 0.0188182 -0.018825 0.0447569 +214 0.0188285 0.0147456 0.0461032 +215 0.0188626 0.015416 0.041072 +216 0.0190811 -0.00419709 0.0686858 +217 0.0195945 0.0084326 0.064095 +218 0.0197498 -0.00217441 0.0583864 +219 0.0198208 0.00539755 0.0587622 +220 0.0200137 0.0324539 0.00354185 +221 0.020151 -0.0145671 0.0500049 +222 0.0203386 -0.00326709 0.0702447 +223 0.0209148 0.00523036 0.0681576 +224 0.0208447 0.0121045 0.0546374 +225 0.0209724 0.00970633 0.0633876 +226 0.020604 -0.0121123 0.00591309 +227 0.0212498 -0.0289526 0.00565549 +228 0.0216078 -0.0380775 0.00479088 +229 0.0216875 -0.00997672 0.0619769 +230 0.0220658 0.00705093 0.0456869 +231 0.0223002 -0.0558455 0.0110476 +232 0.0223137 -0.0154618 0.0494217 +233 0.0229336 0.00417573 0.0589573 +234 0.0231427 0.0278288 0.0125965 +235 0.0231751 0.027241 0.0309726 +236 0.0233259 0.0160686 0.00756079 +237 0.0234095 0.0318943 0.0199392 +238 0.0234462 -0.00393483 0.0583985 +239 0.0235915 -0.0597066 0.0170609 +240 0.0240196 -0.0108777 0.0466362 +241 0.024123 -0.00330273 0.0464733 +242 0.0242099 -0.0321428 0.0398591 +243 0.0244244 0.00347947 0.0416421 +244 0.024564 -0.0175604 0.0433407 +245 0.0253979 -0.0453083 0.0344803 +246 0.0256103 0.0267734 0.0284514 +247 0.0259312 -0.0445208 0.00878379 +248 0.025959 -0.0133125 0.00624018 +249 0.0265967 -0.0369666 0.00635268 +250 0.0273245 -0.0066598 0.0412078 +251 0.0277597 -0.0467651 0.0304517 +252 0.0275944 -0.0515878 0.0207552 +253 0.0282687 0.0208205 0.0174814 +254 0.0290859 0.0112094 0.012597 +255 0.0293048 -0.0474855 0.0256026 +256 0.0296506 -0.0466043 0.0156453 +257 0.0304236 0.0134394 0.031696 +258 0.0304518 -0.0291908 0.00746031 +259 0.03126 -0.044124 0.016095 +260 0.0321715 -0.043346 0.0242104 +261 0.0322352 -0.0402733 0.0141242 +262 0.0323149 0.01052 0.0200521 +263 0.0324768 -0.0397188 0.0271188 +264 0.0325431 -0.0291932 0.0340382 +265 0.0332479 -0.0329826 0.0117351 +266 0.0338676 -0.0346121 0.0252676 +267 0.0341522 -0.00293196 0.033596 +268 0.0341882 -0.0361716 0.0179088 +269 0.0344969 -0.0256263 0.0309923 +270 0.0345138 -0.00958586 0.0123416 +271 0.0348872 -0.0128566 0.0339912 +272 0.0349524 -0.0273994 0.0177976 +273 0.0349556 -0.000677158 0.0209767 +274 0.0350004 -0.028049 0.00876142 +275 0.0353194 -0.0100316 0.0154749 +276 0.0354214 -0.0195455 0.0173172 +277 0.0355775 -0.0309821 0.0107592 +278 0.0360305 -0.0150581 0.0232372 +279 0.0363938 -0.0285041 0.0132933 +280 0.0374738 -0.00607371 0.0123945 +281 0.041317 -0.0210454 0.0131228 +282 0.0425886 -0.0120136 0.0129537 +283 0.0475164 -0.00753527 0.00853843 +284 0.0492593 -0.00704914 0.00938067 +285 0.0496752 -0.0170405 0.0106038 +286 0.0498676 -0.0259318 0.00619626 +287 0.052402 -0.022331 0.00866719 +288 0.0516897 -0.011391 0.0103437 +289 0.0559595 -0.0106346 0.00698866 +290 0.0596531 -0.0214295 0.0059579 +291 0.066312 -0.0158462 0.00759335 +292 0.0672852 -0.00331292 0.00667068 +293 0.0687074 -0.0027598 0.00829441 +294 0.0687083 -0.0084515 0.00881385 +295 0.0702857 -0.00694567 0.00665748 +296 0.02471 0.00101921 0.00688758 +297 0.00641783 -0.0341512 0.0233596 +298 0.024018 0.00854392 0.00722419 +299 0.0251696 0.00942127 0.00784613 +300 -0.019815 0.0686939 0.0189821 +301 0.0416697 -0.017118 0.00864259 +302 -0.00440288 -0.0698432 0.0205811 +303 -0.0033606 0.0600219 0.0217676 +304 0.0268544 0.00322876 0.0080825 +305 0.00855449 0.0107052 0.00928038 +306 0.0219179 0.00585482 0.0121236 +307 0.0199208 0.0175811 0.0336776 +308 0.0210521 -0.0362113 0.0256186 +309 0.0339797 -0.00194129 0.0163861 +310 0.03202 0.000337126 0.0126992 +311 0.0119633 0.0163586 0.0147908 +312 0.0248778 0.0056119 0.0321775 +313 0.00892971 -0.0563678 0.0287948 +314 0.0174837 0.027107 0.0210333 +315 -0.0170518 0.00346089 0.00554363 +316 0.0144974 -0.0120686 0.0314959 +317 0.00336155 -0.00103205 0.0364574 +318 0.00707711 -0.0204903 0.0185209 +319 0.010517 -0.00309481 0.0232445 +320 -0.00559352 0.0373259 0.0172753 +321 -0.00523735 -0.0230725 0.0111224 +322 0.0151072 -0.0538804 0.0213778 +323 0.0347571 -0.0188174 0.0105515 +324 0.0278657 -0.0183642 0.0156758 +325 -0.00338013 -0.0543805 0.0329679 +326 -0.0196332 0.0593213 0.0251138 +327 0.0648163 -0.0143432 0.00627944 +328 -0.00336175 -0.0187472 0.00979996 +329 -0.0059938 -0.0214388 0.00941436 +330 0.0204933 0.0262773 0.00994486 +331 0.0153554 0.00838654 0.0105168 +332 -0.064082 0.064994 0.00682263 +333 -0.0406296 0.0703091 0.0249838 +334 -0.0197677 0.0563929 0.0156108 +335 -0.0506931 0.0781816 0.0304629 +336 0.0171972 -0.00100568 0.011485 +337 0.0314619 -0.0225976 0.00774901 +338 -0.00980694 0.0515267 0.0104574 +339 -0.00435185 0.0493969 0.0137744 +340 0.0449063 -0.0117353 0.00859937 +341 0.00159087 -0.0450385 0.027858 +342 -0.00469537 -0.0637251 0.0233918 +343 0.0424219 -0.0285632 0.00857374 +344 0.0603894 -0.00835109 0.00935053 +345 -0.0147113 -0.0156046 0.00918376 +346 -0.0528157 0.0611754 0.00480955 +347 -0.0173765 -0.00887149 0.00520522 +348 0.0108104 0.02268 0.0130558 +349 -0.00899905 -0.0208443 0.00915416 +350 -0.0449914 0.0768094 0.0302276 +351 -0.0408502 0.06658 0.00836849 +352 -0.0199988 -0.0118916 0.004906 +353 0.00337131 0.0455887 0.0238561 +354 0.00477413 -0.0721541 0.0211645 +355 -0.00344193 -0.049333 0.032475 +356 0.0427245 -0.0268877 0.00738607 +357 0.0272704 -0.0238375 0.00669928 +358 -0.00610544 -0.0476638 0.0181008 +359 -0.00760153 0.0503529 0.00747858 +360 0.0131109 -0.0422224 0.0405109 +361 0.00214561 -0.0490294 0.0151357 +362 -0.0598224 0.0805424 0.0511855 +363 -0.0204542 0.0588165 0.013102 +364 0.059357 -0.0190886 0.00813027 +365 -0.00100716 0.0422264 0.0325724 +366 0.0325535 -0.0244764 0.012522 +367 -0.000431427 -0.0574818 0.0137747 +368 0.0114251 0.0275734 0.00440942 +369 0.00337666 -0.0559724 0.0148659 +370 -0.0262911 0.0586227 0.0207785 +371 -0.0699467 0.0813567 0.0499003 +372 0.0494602 -0.0133111 0.00757754 +373 0.00758285 0.0333008 0.0104911 +374 0.00657287 0.032122 0.00603963 +375 0.000332803 -0.0511328 0.0180756 +376 -0.021764 0.0620607 0.0118108 +377 -0.0454672 0.075167 0.035911 +378 0.00139884 0.045926 0.0128133 +379 0.0176314 0.0311493 0.00370344 +380 -0.0159418 -0.0158578 0.00793814 +381 -0.0229387 0.0691641 0.0166572 +382 -0.00133409 -0.0449329 0.0187829 +383 -0.0538019 0.0611146 0.00198764 +384 0.0305208 -0.00256491 0.0101919 +385 0.0623596 -0.00697151 0.00683979 +386 0.0236819 -0.00777996 0.0526871 +387 0.0118138 -0.0144241 0.0430193 +388 0.0137156 -0.00365078 0.00732253 +389 -0.0257884 0.0686739 0.0150694 +390 -0.0530331 0.060812 0.00248197 +391 -0.000421194 -0.0523335 0.00879177 +392 0.0193846 -0.00072024 0.0649221 +393 0.00485856 0.0133946 0.0114741 +394 -0.0053823 -0.0743714 0.0141262 +395 0.016958 0.0166471 0.00740593 +396 0.0429338 -0.0266961 0.0110582 +397 -0.0650475 0.05473 0.00191127 +398 0.00924818 0.0356698 0.00715588 +399 -0.042468 0.0652669 0.00790867 +400 0.00699205 0.0348997 0.00576165 +401 -0.012123 0.00171435 0.00688121 +402 0.017741 0.00126373 0.0717161 +403 -0.00477874 -0.0228765 0.0123522 +404 -0.05496 0.0793832 0.0329037 +405 -0.0253736 -0.000654191 0.00342534 +406 0.0220159 -0.0128389 0.0555838 +407 0.0187915 0.00366305 0.0653901 +408 -0.0635923 0.0794618 0.0351284 +409 0.0187293 0.00901455 0.0689246 +410 -0.0507436 0.0790633 0.0364811 +411 0.00440962 0.0291856 0.00589534 +412 -0.0610541 0.0815764 0.0467801 +413 -0.0264169 0.0641898 0.0180225 +414 0.0590681 -0.0129818 0.00969293 +415 0.0316732 -0.013669 0.00892731 +416 -0.0368828 0.0732351 0.028231 +417 0.0147007 -0.0293577 0.0425282 +418 -0.00226105 0.042112 0.00818422 +419 -0.022404 0.068624 0.0211714 +420 0.018834 0.0296379 0.0101126 +421 0.0545664 -0.023882 0.00596013 +422 -0.0610274 0.0626039 0.00623226 +423 0.0209345 -0.0123916 0.0558755 +424 -0.064258 0.0639612 0.00701622 +425 -0.0530259 0.0709966 0.0104874 +426 -0.000350232 0.0328643 0.00950357 +427 0.0179821 0.0260225 0.00525665 +428 -0.071629 0.0809096 0.0500374 +429 0.0431333 -0.00662611 0.0109755 +430 -0.0367738 0.072104 0.0272887 +431 -0.00147996 0.0424733 0.00778004 +432 -0.0489442 0.0792518 0.0424775 +433 0.0178184 0.00830923 0.0698262 +434 -0.00256208 -0.0518644 0.0119693 +435 -0.0024457 0.0347988 0.0115191 +436 -0.0226391 0.067054 0.0236986 +437 -0.0250562 0.070839 0.0181046 +438 0.0157661 -0.010775 0.0444953 +439 -0.0587069 0.0610686 0.00549325 +440 -0.0561989 0.0607157 0.00436391 +441 0.0028322 0.0311045 0.0076099 +442 -0.061857 0.079748 0.0514834 +443 -0.0580072 0.0744854 0.0170926 +444 0.017366 0.0281829 0.00449304 +445 0.0175246 0.0303053 0.00632184 +446 -0.0583716 0.0812348 0.0494755 +447 -0.0627638 0.0811059 0.0418948 +448 0.00958337 0.0391723 0.00889538 +449 0.0164997 0.0327763 0.00400793 +450 -0.0100537 -0.019407 0.0104569 +451 0.0535082 -0.023589 0.00757618 +452 -0.0184567 0.0672393 0.0165986 +453 -0.0660887 0.0639515 0.00557639 +454 -0.0085005 0.0591911 0.0132991 +455 0.0527123 -0.00658592 0.00801901 +456 0.00664445 0.0147496 0.00979726 +457 -0.0323364 0.0646841 0.013176 +458 -0.0684981 0.0817682 0.0541475 +459 0.0424951 -0.00680449 0.0104665 +460 -0.01583 0.0638299 0.0140017 +461 -0.0408586 0.0747808 0.0276312 +462 -0.0213675 0.00505684 0.00440033 +463 -0.0609542 0.0784149 0.029815 +464 0.0458286 -0.0196104 0.0115924 +465 0.0619857 -0.0044448 0.00717137 +466 -0.0549453 0.0736446 0.0144159 +467 -0.0660739 0.0797747 0.0511232 +468 -0.0150243 -0.0138696 0.00597473 +469 -0.0208919 0.0664273 0.014553 +470 -0.0583912 0.0766731 0.0277458 +471 -0.00499489 -0.0492059 0.0154875 +472 -0.0177596 -0.0149926 0.00640227 +473 -0.0656257 0.0638276 0.00437301 +474 -0.00111824 -0.0505712 0.010634 +475 -0.0234714 0.0595273 0.0150887 +476 -0.0117477 -0.00786715 0.0107629 +477 -0.0329423 0.0662408 0.012525 +478 -0.0588644 0.0778049 0.0265316 +479 -0.038272 0.0710121 0.0277124 +480 0.0147178 0.0228905 0.00513556 +481 -0.00242697 -0.0228032 0.0106496 +482 -0.00998317 -0.0196685 0.00798312 +483 0.00194711 0.0338412 0.00734265 +484 -0.0101071 0.0571173 0.0108272 +485 -0.000192036 0.0305177 0.010316 +486 -0.0662236 0.0609953 0.00234663 +487 -0.0383437 0.071981 0.0290737 +488 0.0464353 -0.0271448 0.00729223 +489 -0.0113654 0.0558876 0.00985606 +490 -0.0600686 0.0581853 0.00037707 +491 0.0184892 0.00651809 0.072001 +492 -0.0272353 0.0661385 0.0125002 +493 0.0386787 -0.00939756 0.0110365 +494 -0.00702298 -0.0554164 0.0301677 +495 -0.0387296 0.0725599 0.0291973 +496 -0.0195884 -0.00971304 0.00731553 +497 0.000980398 0.0340005 0.00831153 +498 -0.00251349 -0.0493306 0.0137872 +499 -0.0208118 0.00468072 0.00662791 +500 0.0145465 0.0247675 0.00685396 +501 0.0539643 -0.00601143 0.00911787 +502 0.0615879 -0.00432066 0.00875869 +503 -0.0649217 0.0800024 0.0383643 +504 0.00460493 0.00849738 0.0127005 +505 -0.0606311 0.0803611 0.0379233 +506 -0.00316884 0.0400824 0.00969248 +507 -0.0308482 0.067467 0.0126012 +508 0.0120049 0.00511369 0.00824306 +509 0.0117314 0.0134932 0.00784586 +510 0.0067401 0.0222359 0.00786688 +511 0.000365941 0.0444987 0.0334101 +512 0.00589042 0.0427357 0.0325284 +513 0.0134556 0.013691 0.0071386 +514 0.0155774 0.00572549 0.00675779 +515 -0.0442054 0.0654197 0.00607699 +516 0.00863004 0.0184766 0.00878081 +517 -0.0111016 -0.0170398 0.0107756 +518 -0.0162643 0.06208 0.0123266 +519 -0.0670643 0.0628756 0.0047451 +520 -0.0673064 0.0791769 0.0489333 +521 -0.0566743 0.0588231 0.00264455 +522 -0.0713841 0.080001 0.0523997 +523 -0.0690781 0.0794039 0.0521145 +524 -0.0589744 0.0702988 0.0123753 +525 -0.0108026 0.05228 0.00636676 +526 -0.0113486 0.0541547 0.00728553 +527 -0.0299136 0.0686241 0.0165753 +528 0.0505332 -0.0225927 0.00635398 +529 0.0180077 0.0031318 0.0704387 +530 -0.0235313 0.0640143 0.012641 +531 -0.0235569 0.00584404 0.00381922 +532 0.0384718 -0.0113423 0.0144484 +533 0.0182407 0.00232532 0.0728388 +534 -0.0235752 0.00407866 0.00373027 +535 -0.011585 0.0522432 0.00647843 +536 0.0400312 -0.00904366 0.0126741 +537 -0.0178591 -0.000359808 0.00797485 +538 -0.067167 0.0625514 0.00392853 +539 -0.0596438 0.0779391 0.0290601 +540 0.0013543 0.0302152 0.00901705 +541 0.0168301 0.00522322 0.0737244 +542 0.0174324 0.00448014 0.0738384 +543 -0.0618546 0.0649931 0.00590465 +544 0.0194429 0.0304209 0.00452872 +545 -0.0236633 0.0648084 0.0124456 +546 -0.00249493 -0.0562542 0.012985 +547 -0.0025263 -0.0246783 0.0125409 +548 -0.0396392 0.0718092 0.02876 +549 -0.0158083 -0.0164708 0.00645267 +550 0.016879 0.0245859 0.0055459 +551 -0.0688499 0.0811361 0.0461884 +552 0.0290982 -0.00647478 0.00827907 +553 -0.041817 0.0761358 0.0343691 +554 -0.0642688 0.0653922 0.00517065 +555 -0.0162175 0.00239503 0.00694561 +556 0.00467524 0.0360758 0.00643588 +557 -0.0222973 0.0035638 0.00646752 +558 -0.0708092 0.0801688 0.0482801 +559 -0.0549524 0.0787083 0.0296023 +560 -0.0631054 0.0672415 0.00811831 +561 -0.0155444 -0.0163359 0.0060847 +562 -0.0574097 0.0788047 0.0473507 +563 -0.0558952 0.0591814 0.001764 +564 -0.0177409 0.0619627 0.0144786 +565 -0.00178349 -0.0487397 0.0125937 +566 -0.0111058 0.0522074 0.00829904 +567 -0.0260139 0.00360897 0.00461987 +568 -0.0204566 0.00423454 0.00564674 +569 0.00612936 0.0370467 0.00680554 +570 0.010446 0.0313554 0.00705031 +571 -0.0569353 0.05965 0.00118235 +572 -0.0506685 0.0625792 0.00279292 +573 -0.0249761 0.00485573 0.00443819 +574 0.0172421 0.00725128 0.0738262 +575 -0.0219613 0.0643004 0.0138184 +576 -0.00260185 -0.0513557 0.0142694 +577 -0.0167422 0.00259292 0.00779623 +578 0.00214524 0.0341103 0.00650831 +579 -0.0236765 0.00572293 0.004305 +580 -0.0616879 0.0784644 0.0353636 +581 -0.0125522 0.0533024 0.00573952 +582 -0.00373263 -0.048886 0.014509 +583 -0.00253347 -0.0472982 0.0131992 +584 -0.0128746 -0.017623 0.00940414 +585 -5.43548e-05 0.0393803 0.00728201 +586 -0.0258702 0.00405717 0.00525282 +587 0.0183599 0.0265636 0.00640112 +588 0.0459896 -0.0257989 0.0100883 +589 -0.0295424 0.0680594 0.0247957 +590 -0.0245383 0.0634107 0.0123732 +591 0.0066096 0.0377811 0.00691952 +592 -0.0450015 0.0646553 0.00575343 +593 -0.0622505 0.0661482 0.00839783 +594 -0.0256248 0.0608105 0.0161665 +595 0.017488 0.00853314 0.0720965 +596 -0.0596734 0.0705097 0.00992485 +597 -0.0665798 0.0628689 0.00493615 +598 -0.0624322 0.0664941 0.0080812 +599 0.0436037 -0.00911409 0.00950451 +600 -0.0258241 0.00183578 0.00455937 +601 -0.0702703 0.0796913 0.0546337 +602 -0.027947 0.0630495 0.0231884 +603 -0.0601839 0.0704633 0.0106076 +604 -0.019796 -0.0130118 0.0069497 +605 -0.0183149 0.0630548 0.012418 +606 -0.0302535 0.0701272 0.02364 +607 -0.0574291 0.0790851 0.0314511 +608 -0.0506885 0.0650762 0.00396145 +609 -0.021101 0.0616869 0.0137094 +610 -0.0331684 0.0670427 0.023997 +611 0.0134393 0.00644533 0.00718965 +612 -0.0111807 -0.0194906 0.00818236 +613 -0.0255718 0.00304117 0.00332801 +614 -0.0126697 -0.015488 0.00653208 +615 -0.0247074 0.00660999 0.00551935 +616 0.0173416 0.0031807 0.0727906 +617 0.0172416 0.0236783 0.00588169 +618 0.0190309 0.0293428 0.00437137 +619 0.016715 0.00646681 0.0747173 +620 -0.0362286 0.072292 0.023504 +621 -0.0193589 -0.00042516 0.00470745 +622 -0.0218861 0.0643631 0.0125137 +623 -0.0102557 0.0512168 0.00711881 +624 0.0404202 -0.00631757 0.0116411 +625 0.0462272 -0.00679819 0.0101561 +626 -0.0259792 0.0656558 0.0150971 +627 0.0162732 0.0229634 0.00624384 +628 0.00353474 0.0364474 0.00843339 +629 4.6368e-06 0.0388726 0.00973083 +630 -0.0216501 0.0633078 0.012475 +631 -0.0653553 0.0635995 0.0060088 +632 -0.0129397 0.0533345 0.00604151 +633 -0.00189413 -0.0244631 0.013557 +634 -0.0610974 0.0673557 0.00916116 +635 0.0169636 0.00823874 0.0726305 +636 -0.0262169 0.00566462 0.00486021 +637 -0.00105663 -0.050339 0.013034 +638 -0.0522352 0.0618469 0.00239028 +639 -0.0658611 0.0623674 0.00600767 +640 -0.0308719 0.0671807 0.0240148 +641 -0.0271033 0.0631674 0.0232081 +642 0.000463176 0.0377435 0.00713404 +643 0.0197653 -0.0105149 0.0573133 +644 -0.0261272 0.00574879 0.00514751 +645 -0.0256133 0.00236555 0.00535812 +646 0.0395658 -0.00664927 0.0115095 +647 -0.0346515 0.0704144 0.0260764 +648 -0.0676857 0.0619198 0.00410476 +649 -0.0352382 0.0722683 0.0261851 +650 -0.0489272 0.0632235 0.00329626 +651 -0.0514659 0.0617489 0.00295197 +652 -0.070483 0.0805389 0.0464472 +$EndNodes +$Elements +1654 +1 4 0 26 15 543 25 +2 4 0 227 308 190 188 +3 4 0 203 353 199 163 +4 4 0 331 305 504 150 +5 4 0 142 328 128 138 +6 4 0 490 439 18 571 +7 4 0 364 289 287 414 +8 4 0 296 336 304 298 +9 4 0 564 419 300 381 +10 4 0 398 569 373 591 +11 4 0 486 473 639 422 +12 4 0 338 89 566 489 +13 4 0 332 554 543 424 +14 4 0 80 67 71 302 +15 4 0 149 146 109 108 +16 4 0 98 90 375 342 +17 4 0 341 308 325 313 +18 4 0 147 314 126 116 +19 4 0 124 318 156 131 +20 4 0 245 322 206 308 +21 4 0 348 311 516 186 +22 4 0 135 150 319 151 +23 4 0 147 314 307 311 +24 4 0 464 588 301 528 +25 4 0 461 33 35 333 +26 4 0 196 192 373 314 +27 4 0 108 81 302 122 +28 4 0 366 258 227 357 +29 4 0 511 107 512 353 +30 4 0 146 170 354 172 +31 4 0 297 175 156 130 +32 4 0 130 297 175 308 +33 4 0 318 159 319 195 +34 4 0 154 123 122 342 +35 4 0 261 308 259 260 +36 4 0 132 142 128 318 +37 4 0 241 250 240 205 +38 4 0 226 227 248 324 +39 4 0 575 609 475 49 +40 4 0 375 91 123 90 +41 4 0 260 308 255 251 +42 4 0 517 612 63 482 +43 4 0 120 117 131 297 +44 4 0 318 131 297 156 +45 4 0 147 319 311 307 +46 4 0 131 120 297 130 +47 4 0 120 297 111 117 +48 4 0 308 174 206 360 +49 4 0 148 313 325 175 +50 4 0 148 313 175 174 +51 4 0 302 80 122 81 +52 4 0 107 353 511 110 +53 4 0 322 231 198 197 +54 4 0 61 58 564 57 +55 4 0 240 386 212 221 +56 4 0 121 297 143 117 +57 4 0 121 297 117 111 +58 4 0 307 235 314 182 +59 4 0 307 314 166 182 +60 4 0 417 308 175 316 +61 4 0 308 175 360 417 +62 4 0 601 9 458 1 +63 4 0 459 429 536 599 +64 4 0 211 242 206 308 +65 4 0 528 588 301 356 +66 4 0 316 297 308 175 +67 4 0 197 188 308 228 +68 4 0 231 308 228 197 +69 4 0 231 197 322 308 +70 4 0 188 197 308 361 +71 4 0 322 361 308 197 +72 4 0 259 308 256 255 +73 4 0 298 306 304 299 +74 4 0 302 342 146 122 +75 4 0 251 322 245 308 +76 4 0 298 306 299 236 +77 4 0 342 302 169 129 +78 4 0 157 319 331 150 +79 4 0 190 195 324 227 +80 4 0 146 342 354 154 +81 4 0 190 297 308 324 +82 4 0 236 254 306 299 +83 4 0 354 179 201 322 +84 4 0 308 297 188 361 +85 4 0 361 188 164 297 +86 4 0 195 165 190 318 +87 4 0 307 215 257 235 +88 4 0 194 235 215 307 +89 4 0 174 129 148 313 +90 4 0 169 313 129 174 +91 4 0 322 255 251 201 +92 4 0 366 265 308 258 +93 4 0 227 308 258 366 +94 4 0 258 308 249 265 +95 4 0 227 308 228 258 +96 4 0 448 192 373 196 +97 4 0 228 308 249 258 +98 4 0 296 298 514 336 +99 4 0 125 150 348 126 +100 4 0 125 160 348 150 +101 4 0 244 264 242 316 +102 4 0 264 316 244 271 +103 4 0 224 233 225 219 +104 4 0 107 353 163 199 +105 4 0 217 223 219 225 +106 4 0 308 174 313 206 +107 4 0 206 313 179 174 +108 4 0 241 230 212 233 +109 4 0 241 233 212 218 +110 4 0 267 278 312 273 +111 4 0 267 312 262 273 +112 4 0 206 179 322 245 +113 4 0 242 245 206 308 +114 4 0 144 319 159 157 +115 4 0 265 308 266 272 +116 4 0 218 219 392 233 +117 4 0 264 324 316 271 +118 4 0 324 308 264 316 +119 4 0 297 318 117 131 +120 4 0 128 117 318 124 +121 4 0 354 207 201 177 +122 4 0 207 177 354 184 +123 4 0 155 163 353 203 +124 4 0 131 297 156 130 +125 4 0 395 330 236 202 +126 4 0 164 142 318 190 +127 4 0 253 314 234 311 +128 4 0 307 314 147 166 +129 4 0 331 234 253 254 +130 4 0 306 236 298 331 +131 4 0 156 297 316 175 +132 4 0 324 319 318 316 +133 4 0 297 324 316 308 +134 4 0 373 314 102 125 +135 4 0 167 155 378 192 +136 4 0 278 324 272 269 +137 4 0 278 276 272 324 +138 4 0 319 159 157 336 +139 4 0 267 257 312 243 +140 4 0 307 215 243 257 +141 4 0 156 297 318 316 +142 4 0 207 354 170 184 +143 4 0 124 144 139 156 +144 4 0 267 312 250 243 +145 4 0 144 151 139 319 +146 4 0 318 316 319 144 +147 4 0 316 139 319 144 +148 4 0 139 144 316 156 +149 4 0 316 191 312 319 +150 4 0 316 191 317 156 +151 4 0 313 308 175 174 +152 4 0 253 234 331 311 +153 4 0 331 395 234 236 +154 4 0 272 265 308 366 +155 4 0 103 140 133 510 +156 4 0 235 199 246 314 +157 4 0 246 237 314 199 +158 4 0 144 151 319 157 +159 4 0 92 157 151 144 +160 4 0 92 159 157 144 +161 4 0 395 234 236 330 +162 4 0 395 330 202 348 +163 4 0 348 330 202 209 +164 4 0 324 312 316 271 +165 4 0 266 308 324 272 +166 4 0 324 366 308 227 +167 4 0 242 264 245 308 +168 4 0 272 266 269 324 +169 4 0 135 151 319 139 +170 4 0 40 35 28 29 +171 4 0 88 148 129 342 +172 4 0 325 342 148 88 +173 4 0 314 116 147 166 +174 4 0 77 353 320 94 +175 4 0 331 262 319 306 +176 4 0 319 317 139 316 +177 4 0 450 329 482 328 +178 4 0 183 307 147 166 +179 4 0 188 361 176 197 +180 4 0 169 179 313 174 +181 4 0 314 196 348 373 +182 4 0 102 84 116 353 +183 4 0 102 77 84 353 +184 4 0 191 147 319 317 +185 4 0 307 262 257 312 +186 4 0 307 257 246 235 +187 4 0 307 257 262 246 +188 4 0 128 318 144 124 +189 4 0 246 314 237 253 +190 4 0 314 203 237 234 +191 4 0 142 128 318 138 +192 4 0 253 237 234 314 +193 4 0 306 319 331 336 +194 4 0 307 314 235 246 +195 4 0 316 250 312 191 +196 4 0 450 403 349 329 +197 4 0 121 297 101 143 +198 4 0 382 164 101 297 +199 4 0 369 198 322 193 +200 4 0 264 266 324 269 +201 4 0 322 354 170 207 +202 4 0 322 170 193 207 +203 4 0 353 84 116 110 +204 4 0 70 302 68 83 +205 4 0 331 311 234 395 +206 4 0 323 493 282 301 +207 4 0 269 278 324 271 +208 4 0 278 312 324 271 +209 4 0 207 170 180 184 +210 4 0 207 170 193 180 +211 4 0 325 130 175 308 +212 4 0 146 354 170 154 +213 4 0 354 302 342 146 +214 4 0 161 348 510 181 +215 4 0 182 314 199 235 +216 4 0 322 354 369 170 +217 4 0 231 207 322 198 +218 4 0 313 322 375 341 +219 4 0 375 361 341 322 +220 4 0 322 207 193 198 +221 4 0 297 143 164 101 +222 4 0 221 213 240 232 +223 4 0 190 188 308 297 +224 4 0 341 361 375 382 +225 4 0 341 308 313 322 +226 4 0 134 158 184 354 +227 4 0 247 308 261 249 +228 4 0 263 308 260 251 +229 4 0 318 319 159 144 +230 4 0 309 262 306 319 +231 4 0 250 204 243 312 +232 4 0 448 192 167 378 +233 4 0 37 333 620 35 +234 4 0 37 33 333 35 +235 4 0 297 318 316 324 +236 4 0 167 448 378 153 +237 4 0 212 218 233 219 +238 4 0 88 325 342 494 +239 4 0 246 307 314 253 +240 4 0 307 253 246 262 +241 4 0 126 311 150 348 +242 4 0 388 611 336 514 +243 4 0 348 234 420 314 +244 4 0 236 254 331 306 +245 4 0 348 314 311 234 +246 4 0 211 308 360 417 +247 4 0 373 102 320 125 +248 4 0 316 250 191 438 +249 4 0 250 205 191 438 +250 4 0 254 262 306 309 +251 4 0 254 309 306 310 +252 4 0 299 254 306 310 +253 4 0 331 262 306 254 +254 4 0 292 294 295 293 +255 4 0 194 307 215 204 +256 4 0 304 306 384 299 +257 4 0 267 312 257 262 +258 4 0 353 192 378 155 +259 4 0 319 159 336 195 +260 4 0 353 192 373 378 +261 4 0 336 185 388 195 +262 4 0 312 250 271 267 +263 4 0 271 250 312 316 +264 4 0 261 249 308 265 +265 4 0 268 308 265 261 +266 4 0 247 308 249 228 +267 4 0 227 195 324 226 +268 4 0 366 324 415 337 +269 4 0 337 366 324 357 +270 4 0 190 195 318 324 +271 4 0 156 318 124 144 +272 4 0 263 266 308 264 +273 4 0 251 263 308 264 +274 4 0 197 198 322 369 +275 4 0 154 354 369 342 +276 4 0 188 308 228 227 +277 4 0 79 328 138 92 +278 4 0 316 317 139 156 +279 4 0 360 175 308 174 +280 4 0 255 251 308 322 +281 4 0 255 256 252 308 +282 4 0 247 228 231 308 +283 4 0 247 308 231 256 +284 4 0 134 149 394 354 +285 4 0 83 162 96 302 +286 4 0 161 373 140 348 +287 4 0 88 67 302 68 +288 4 0 302 97 88 68 +289 4 0 512 166 314 182 +290 4 0 420 192 314 234 +291 4 0 348 330 420 234 +292 4 0 192 314 234 203 +293 4 0 91 123 105 115 +294 4 0 394 70 302 81 +295 4 0 309 273 262 319 +296 4 0 319 262 312 273 +297 4 0 67 302 68 70 +298 4 0 271 278 312 267 +299 4 0 66 57 326 58 +300 4 0 188 136 176 361 +301 4 0 157 331 185 504 +302 4 0 136 361 188 164 +303 4 0 244 250 271 316 +304 4 0 71 302 67 70 +305 4 0 244 213 232 240 +306 4 0 81 302 71 70 +307 4 0 354 149 108 146 +308 4 0 314 237 203 199 +309 4 0 506 378 435 629 +310 4 0 244 438 316 213 +311 4 0 97 302 169 162 +312 4 0 244 316 438 250 +313 4 0 313 129 342 169 +314 4 0 382 113 101 164 +315 4 0 506 435 378 94 +316 4 0 91 123 85 105 +317 4 0 308 264 245 251 +318 4 0 242 264 308 316 +319 4 0 450 349 482 329 +320 4 0 314 373 348 125 +321 4 0 92 138 159 144 +322 4 0 395 311 234 348 +323 4 0 278 273 324 312 +324 4 0 373 378 435 320 +325 4 0 147 311 319 135 +326 4 0 126 311 135 150 +327 4 0 126 135 311 147 +328 4 0 314 348 311 126 +329 4 0 83 302 82 70 +330 4 0 378 435 629 373 +331 4 0 195 159 165 318 +332 4 0 316 312 324 319 +333 4 0 156 175 316 387 +334 4 0 336 298 514 331 +335 4 0 88 342 129 302 +336 4 0 319 307 331 311 +337 4 0 253 314 311 307 +338 4 0 311 331 253 307 +339 4 0 297 341 308 130 +340 4 0 314 348 126 125 +341 4 0 147 314 311 126 +342 4 0 61 339 99 338 +343 4 0 250 204 312 191 +344 4 0 305 185 508 331 +345 4 0 211 242 308 316 +346 4 0 211 308 417 316 +347 4 0 213 316 211 417 +348 4 0 214 215 230 204 +349 4 0 244 316 242 211 +350 4 0 244 211 213 316 +351 4 0 465 501 344 502 +352 4 0 108 354 302 394 +353 4 0 313 129 148 342 +354 4 0 337 324 415 248 +355 4 0 337 258 366 357 +356 4 0 121 101 297 111 +357 4 0 382 101 111 297 +358 4 0 157 159 185 336 +359 4 0 226 336 195 324 +360 4 0 307 262 331 253 +361 4 0 307 262 319 331 +362 4 0 331 254 253 262 +363 4 0 248 336 552 296 +364 4 0 319 324 195 336 +365 4 0 248 296 226 336 +366 4 0 324 248 336 552 +367 4 0 147 183 191 307 +368 4 0 282 281 276 323 +369 4 0 281 323 282 301 +370 4 0 109 119 105 122 +371 4 0 297 143 117 318 +372 4 0 109 122 105 80 +373 4 0 308 366 324 272 +374 4 0 297 318 324 190 +375 4 0 297 190 164 318 +376 4 0 214 204 230 212 +377 4 0 224 212 214 230 +378 4 0 297 143 318 164 +379 4 0 264 308 324 266 +380 4 0 264 269 324 271 +381 4 0 132 117 143 318 +382 4 0 130 297 341 120 +383 4 0 341 130 120 98 +384 4 0 277 343 356 279 +385 4 0 325 308 175 313 +386 4 0 109 81 108 122 +387 4 0 109 122 108 146 +388 4 0 348 234 395 330 +389 4 0 341 111 120 297 +390 4 0 341 100 98 120 +391 4 0 341 111 100 120 +392 4 0 226 336 324 248 +393 4 0 318 319 324 195 +394 4 0 275 270 324 309 +395 4 0 309 336 324 319 +396 4 0 552 270 336 324 +397 4 0 273 309 275 324 +398 4 0 403 328 329 450 +399 4 0 382 111 341 297 +400 4 0 361 322 308 341 +401 4 0 361 341 308 297 +402 4 0 342 85 73 90 +403 4 0 342 73 85 80 +404 4 0 323 324 366 276 +405 4 0 361 297 164 382 +406 4 0 96 82 83 302 +407 4 0 45 647 44 42 +408 4 0 179 354 201 177 +409 4 0 53 621 54 347 +410 4 0 117 124 131 318 +411 4 0 156 144 316 318 +412 4 0 369 198 193 141 +413 4 0 342 302 88 67 +414 4 0 67 80 342 302 +415 4 0 73 80 342 67 +416 4 0 342 73 67 76 +417 4 0 372 528 289 285 +418 4 0 285 528 289 287 +419 4 0 355 98 325 494 +420 4 0 122 119 105 123 +421 4 0 394 82 134 302 +422 4 0 494 88 76 342 +423 4 0 109 81 122 80 +424 4 0 447 580 503 505 +425 4 0 114 118 141 145 +426 4 0 311 150 319 135 +427 4 0 108 122 302 146 +428 4 0 204 307 183 194 +429 4 0 191 204 307 183 +430 4 0 382 101 100 111 +431 4 0 382 111 100 341 +432 4 0 318 159 138 144 +433 4 0 588 281 301 356 +434 4 0 87 61 77 57 +435 4 0 318 159 165 138 +436 4 0 7 12 2 486 +437 4 0 316 191 319 317 +438 4 0 208 196 449 445 +439 4 0 322 369 354 313 +440 4 0 354 158 177 162 +441 4 0 354 169 162 179 +442 4 0 313 369 354 342 +443 4 0 179 162 354 177 +444 4 0 130 98 341 355 +445 4 0 325 130 341 355 +446 4 0 337 357 324 248 +447 4 0 324 357 227 248 +448 4 0 588 281 464 301 +449 4 0 375 341 382 98 +450 4 0 454 75 61 155 +451 4 0 353 77 84 74 +452 4 0 331 305 185 504 +453 4 0 311 331 319 150 +454 4 0 378 339 167 106 +455 4 0 318 190 142 165 +456 4 0 138 142 165 318 +457 4 0 18 12 397 14 +458 4 0 298 514 331 513 +459 4 0 118 137 141 168 +460 4 0 298 331 236 395 +461 4 0 395 298 331 513 +462 4 0 93 157 92 159 +463 4 0 354 158 184 177 +464 4 0 151 157 92 93 +465 4 0 78 93 151 92 +466 4 0 378 448 629 153 +467 4 0 102 314 126 125 +468 4 0 126 116 314 102 +469 4 0 61 72 303 75 +470 4 0 39 461 350 553 +471 4 0 350 39 33 461 +472 4 0 311 331 513 395 +473 4 0 311 331 305 509 +474 4 0 353 102 314 116 +475 4 0 204 215 243 307 +476 4 0 106 153 167 378 +477 4 0 97 162 83 302 +478 4 0 107 353 199 512 +479 4 0 297 188 164 190 +480 4 0 147 319 139 135 +481 4 0 77 353 87 74 +482 4 0 353 203 199 314 +483 4 0 512 314 353 199 +484 4 0 37 38 29 35 +485 4 0 485 140 373 125 +486 4 0 398 448 373 196 +487 4 0 196 570 373 398 +488 4 0 324 248 552 415 +489 4 0 415 270 552 324 +490 4 0 52 57 594 564 +491 4 0 285 289 414 287 +492 4 0 438 250 205 240 +493 4 0 524 425 25 17 +494 4 0 29 25 524 425 +495 4 0 87 77 61 353 +496 4 0 93 92 138 159 +497 4 0 93 92 79 138 +498 4 0 203 192 353 155 +499 4 0 192 353 314 203 +500 4 0 88 302 129 97 +501 4 0 169 342 354 302 +502 4 0 147 319 317 139 +503 4 0 435 426 629 373 +504 4 0 197 168 369 176 +505 4 0 369 176 361 197 +506 4 0 157 151 319 150 +507 4 0 307 319 312 191 +508 4 0 312 307 191 204 +509 4 0 628 373 441 374 +510 4 0 513 331 311 509 +511 4 0 49 594 413 46 +512 4 0 303 163 87 61 +513 4 0 146 342 154 122 +514 4 0 274 366 415 337 +515 4 0 274 258 366 337 +516 4 0 87 57 74 66 +517 4 0 304 306 336 384 +518 4 0 204 250 205 191 +519 4 0 110 74 66 87 +520 4 0 163 87 61 353 +521 4 0 204 205 250 241 +522 4 0 387 438 213 316 +523 4 0 150 160 348 311 +524 4 0 313 369 342 375 +525 4 0 313 322 369 375 +526 4 0 97 129 169 302 +527 4 0 504 305 393 150 +528 4 0 181 348 500 187 +529 4 0 610 527 42 44 +530 4 0 44 527 42 620 +531 4 0 311 305 456 509 +532 4 0 311 509 456 516 +533 4 0 365 512 166 116 +534 4 0 116 512 166 314 +535 4 0 509 305 508 331 +536 4 0 322 369 193 170 +537 4 0 535 526 581 632 +538 4 0 182 314 512 199 +539 4 0 497 441 373 540 +540 4 0 37 42 46 527 +541 4 0 500 209 187 348 +542 4 0 312 257 307 243 +543 4 0 323 366 281 276 +544 4 0 348 420 209 196 +545 4 0 366 279 276 272 +546 4 0 202 500 186 348 +547 4 0 386 406 221 232 +548 4 0 64 526 62 489 +549 4 0 336 159 185 195 +550 4 0 404 24 559 335 +551 4 0 404 24 607 559 +552 4 0 384 336 552 270 +553 4 0 244 240 438 213 +554 4 0 244 438 240 250 +555 4 0 430 461 620 333 +556 4 0 461 333 35 620 +557 4 0 61 564 64 334 +558 4 0 381 437 47 413 +559 4 0 279 277 265 258 +560 4 0 279 277 258 274 +561 4 0 186 500 181 348 +562 4 0 140 510 348 160 +563 4 0 377 410 36 350 +564 4 0 202 330 236 209 +565 4 0 380 345 614 468 +566 4 0 99 339 378 106 +567 4 0 378 106 418 99 +568 4 0 378 448 373 629 +569 4 0 194 235 307 182 +570 4 0 194 307 166 182 +571 4 0 194 307 183 166 +572 4 0 353 373 320 378 +573 4 0 68 97 83 302 +574 4 0 347 496 604 476 +575 4 0 161 181 411 373 +576 4 0 570 374 400 368 +577 4 0 40 38 35 29 +578 4 0 364 289 327 528 +579 4 0 324 309 319 273 +580 4 0 353 378 320 94 +581 4 0 358 91 471 375 +582 4 0 134 394 302 354 +583 4 0 394 149 108 354 +584 4 0 172 354 146 149 +585 4 0 382 358 471 375 +586 4 0 101 382 90 358 +587 4 0 651 346 638 390 +588 4 0 382 90 100 101 +589 4 0 334 594 564 475 +590 4 0 369 361 375 322 +591 4 0 322 197 369 361 +592 4 0 342 325 98 494 +593 4 0 325 313 148 342 +594 4 0 342 325 375 98 +595 4 0 115 369 123 367 +596 4 0 342 98 76 494 +597 4 0 369 375 576 115 +598 4 0 353 512 116 314 +599 4 0 336 304 552 296 +600 4 0 336 306 304 298 +601 4 0 226 514 336 296 +602 4 0 108 302 81 394 +603 4 0 181 411 373 374 +604 4 0 26 440 571 383 +605 4 0 26 383 346 440 +606 4 0 211 360 308 206 +607 4 0 87 74 57 77 +608 4 0 358 113 101 382 +609 4 0 195 388 336 226 +610 4 0 241 233 218 238 +611 4 0 155 339 378 353 +612 4 0 345 79 468 476 +613 4 0 213 316 417 175 +614 4 0 387 316 213 175 +615 4 0 312 307 262 319 +616 4 0 435 485 426 373 +617 4 0 435 373 125 485 +618 4 0 299 310 306 384 +619 4 0 26 425 25 34 +620 4 0 118 114 367 434 +621 4 0 26 34 25 608 +622 4 0 223 222 529 392 +623 4 0 527 38 37 35 +624 4 0 37 527 46 38 +625 4 0 342 123 90 375 +626 4 0 342 123 85 90 +627 4 0 335 350 33 35 +628 4 0 350 461 33 35 +629 4 0 85 91 90 123 +630 4 0 259 247 308 261 +631 4 0 629 628 448 373 +632 4 0 633 142 328 128 +633 4 0 629 497 628 373 +634 4 0 303 61 87 72 +635 4 0 236 254 234 331 +636 4 0 341 98 325 355 +637 4 0 373 570 400 569 +638 4 0 398 570 373 569 +639 4 0 49 413 527 46 +640 4 0 49 46 527 457 +641 4 0 49 626 48 527 +642 4 0 241 204 243 250 +643 4 0 49 527 48 457 +644 4 0 392 218 233 238 +645 4 0 233 392 238 223 +646 4 0 178 198 197 141 +647 4 0 198 197 141 369 +648 4 0 364 290 287 528 +649 4 0 419 381 564 413 +650 4 0 92 78 79 59 +651 4 0 192 373 314 353 +652 4 0 386 406 238 423 +653 4 0 367 369 137 391 +654 4 0 437 413 419 606 +655 4 0 413 437 47 606 +656 4 0 239 252 322 255 +657 4 0 454 61 339 155 +658 4 0 34 466 425 29 +659 4 0 221 386 232 240 +660 4 0 60 64 489 484 +661 4 0 484 65 60 64 +662 4 0 212 386 218 221 +663 4 0 241 240 386 212 +664 4 0 241 205 240 212 +665 4 0 607 24 16 470 +666 4 0 620 42 37 527 +667 4 0 37 333 42 620 +668 4 0 95 87 66 69 +669 4 0 113 164 382 361 +670 4 0 410 30 432 21 +671 4 0 371 1 522 458 +672 4 0 527 47 43 40 +673 4 0 596 425 17 15 +674 4 0 393 456 160 311 +675 4 0 110 95 87 66 +676 4 0 160 311 456 516 +677 4 0 512 511 365 166 +678 4 0 353 511 365 512 +679 4 0 128 144 318 138 +680 4 0 341 130 325 308 +681 4 0 87 61 57 58 +682 4 0 419 58 564 72 +683 4 0 414 289 327 364 +684 4 0 320 378 435 94 +685 4 0 364 528 287 289 +686 4 0 212 221 205 240 +687 4 0 134 172 149 354 +688 4 0 134 172 354 184 +689 4 0 319 147 191 307 +690 4 0 589 641 606 436 +691 4 0 347 79 59 476 +692 4 0 345 79 476 92 +693 4 0 92 138 144 328 +694 4 0 86 92 144 328 +695 4 0 32 399 34 38 +696 4 0 306 309 336 310 +697 4 0 347 604 468 476 +698 4 0 347 468 79 476 +699 4 0 614 345 79 468 +700 4 0 384 310 336 270 +701 4 0 439 25 26 422 +702 4 0 196 192 314 420 +703 4 0 348 420 196 314 +704 4 0 132 143 142 318 +705 4 0 164 142 143 318 +706 4 0 386 406 423 221 +707 4 0 35 527 38 40 +708 4 0 158 354 96 162 +709 4 0 169 302 354 162 +710 4 0 334 475 564 363 +711 4 0 155 61 303 75 +712 4 0 94 353 378 339 +713 4 0 224 233 219 212 +714 4 0 214 215 204 194 +715 4 0 204 243 230 241 +716 4 0 204 230 212 241 +717 4 0 391 474 369 136 +718 4 0 286 588 528 356 +719 4 0 35 620 527 47 +720 4 0 136 474 361 565 +721 4 0 566 526 632 64 +722 4 0 490 439 11 14 +723 4 0 209 330 420 348 +724 4 0 35 527 40 47 +725 4 0 76 342 73 98 +726 4 0 77 353 102 320 +727 4 0 268 308 261 260 +728 4 0 167 155 339 378 +729 4 0 465 289 385 344 +730 4 0 255 308 260 259 +731 4 0 335 24 470 33 +732 4 0 559 24 470 335 +733 4 0 522 1 371 428 +734 4 0 347 53 496 54 +735 4 0 559 24 607 470 +736 4 0 476 347 496 54 +737 4 0 312 204 243 307 +738 4 0 230 215 243 204 +739 4 0 241 218 212 386 +740 4 0 241 238 218 386 +741 4 0 29 33 28 23 +742 4 0 23 335 559 470 +743 4 0 297 382 361 341 +744 4 0 336 611 185 331 +745 4 0 388 185 336 611 +746 4 0 353 373 102 320 +747 4 0 373 102 314 353 +748 4 0 44 527 606 610 +749 4 0 74 110 84 353 +750 4 0 610 527 606 413 +751 4 0 325 341 375 98 +752 4 0 369 136 137 391 +753 4 0 169 354 342 313 +754 4 0 274 366 279 281 +755 4 0 281 366 279 276 +756 4 0 322 313 206 308 +757 4 0 414 289 344 385 +758 4 0 114 546 367 434 +759 4 0 367 391 434 369 +760 4 0 155 163 303 61 +761 4 0 47 620 527 44 +762 4 0 384 304 552 336 +763 4 0 384 310 306 336 +764 4 0 99 378 339 94 +765 4 0 506 94 378 99 +766 4 0 365 353 512 116 +767 4 0 378 99 418 506 +768 4 0 478 23 559 470 +769 4 0 328 86 633 128 +770 4 0 265 308 268 266 +771 4 0 268 308 263 266 +772 4 0 564 419 436 58 +773 4 0 460 75 564 65 +774 4 0 339 61 99 94 +775 4 0 518 564 65 460 +776 4 0 643 216 229 392 +777 4 0 342 88 76 67 +778 4 0 26 422 11 439 +779 4 0 26 440 439 571 +780 4 0 411 161 373 441 +781 4 0 442 467 412 10 +782 4 0 350 377 24 33 +783 4 0 225 409 217 223 +784 4 0 410 377 24 350 +785 4 0 24 350 33 335 +786 4 0 371 522 523 458 +787 4 0 278 324 273 276 +788 4 0 273 324 275 276 +789 4 0 170 354 172 184 +790 4 0 169 179 354 313 +791 4 0 607 16 24 580 +792 4 0 367 391 137 118 +793 4 0 35 620 37 527 +794 4 0 548 33 461 333 +795 4 0 414 385 344 294 +796 4 0 414 289 288 344 +797 4 0 65 64 484 454 +798 4 0 93 79 78 401 +799 4 0 375 382 358 90 +800 4 0 413 575 564 594 +801 4 0 187 181 368 189 +802 4 0 358 375 90 91 +803 4 0 275 276 324 323 +804 4 0 493 270 323 275 +805 4 0 532 323 276 275 +806 4 0 324 270 323 415 +807 4 0 275 323 324 270 +808 4 0 157 331 319 336 +809 4 0 454 339 61 338 +810 4 0 527 47 507 43 +811 4 0 74 87 110 353 +812 4 0 61 353 339 155 +813 4 0 444 445 618 379 +814 4 0 173 133 160 510 +815 4 0 352 604 468 347 +816 4 0 161 181 373 348 +817 4 0 23 335 470 33 +818 4 0 181 187 374 373 +819 4 0 29 35 28 33 +820 4 0 348 187 181 373 +821 4 0 562 10 412 447 +822 4 0 10 580 503 447 +823 4 0 399 351 34 38 +824 4 0 515 592 399 32 +825 4 0 434 112 637 474 +826 4 0 134 82 96 302 +827 4 0 224 230 233 212 +828 4 0 134 302 96 354 +829 4 0 302 354 162 96 +830 4 0 376 64 60 564 +831 4 0 606 640 589 45 +832 4 0 369 137 168 141 +833 4 0 113 361 583 136 +834 4 0 197 369 168 141 +835 4 0 12 7 4 14 +836 4 0 510 181 173 171 +837 4 0 61 339 353 94 +838 4 0 369 154 170 354 +839 4 0 404 607 24 21 +840 4 0 411 374 578 441 +841 4 0 500 186 189 480 +842 4 0 535 526 632 566 +843 4 0 628 441 497 483 +844 4 0 478 23 28 559 +845 4 0 28 335 559 23 +846 4 0 93 92 78 79 +847 4 0 554 473 631 453 +848 4 0 198 178 193 141 +849 4 0 187 444 209 500 +850 4 0 226 388 336 514 +851 4 0 287 464 285 528 +852 4 0 528 301 285 372 +853 4 0 497 629 426 373 +854 4 0 394 302 70 82 +855 4 0 64 61 454 75 +856 4 0 444 587 618 445 +857 4 0 467 458 371 523 +858 4 0 371 523 520 467 +859 4 0 371 520 551 467 +860 4 0 385 465 294 292 +861 4 0 468 604 345 476 +862 4 0 584 517 63 345 +863 4 0 176 136 137 369 +864 4 0 439 440 18 571 +865 4 0 490 26 11 439 +866 4 0 324 366 227 357 +867 4 0 606 413 419 436 +868 4 0 527 48 477 507 +869 4 0 527 477 48 457 +870 4 0 527 492 48 507 +871 4 0 527 626 48 492 +872 4 0 134 354 96 158 +873 4 0 62 64 489 60 +874 4 0 52 57 370 594 +875 4 0 326 52 55 564 +876 4 0 524 425 17 19 +877 4 0 373 441 161 540 +878 4 0 373 161 140 540 +879 4 0 66 326 55 58 +880 4 0 58 326 55 564 +881 4 0 310 309 336 270 +882 4 0 324 270 336 309 +883 4 0 157 336 185 331 +884 4 0 181 411 171 161 +885 4 0 640 589 641 606 +886 4 0 537 557 621 54 +887 4 0 282 285 340 288 +888 4 0 372 285 288 340 +889 4 0 382 100 98 341 +890 4 0 502 294 465 292 +891 4 0 43 34 351 38 +892 4 0 221 240 213 205 +893 4 0 438 240 205 213 +894 4 0 425 466 524 29 +895 4 0 354 302 146 108 +896 4 0 435 426 506 629 +897 4 0 497 506 426 629 +898 4 0 187 181 374 368 +899 4 0 517 79 614 345 +900 4 0 342 90 73 98 +901 4 0 180 141 178 152 +902 4 0 178 152 141 168 +903 4 0 193 180 141 178 +904 4 0 140 161 348 510 +905 4 0 9 442 13 362 +906 4 0 442 9 13 467 +907 4 0 408 505 503 580 +908 4 0 607 580 408 16 +909 4 0 327 289 414 385 +910 4 0 372 284 283 340 +911 4 0 359 89 526 566 +912 4 0 607 539 478 470 +913 4 0 140 373 125 348 +914 4 0 328 86 92 517 +915 4 0 527 47 44 606 +916 4 0 155 163 61 353 +917 4 0 367 391 118 434 +918 4 0 338 64 61 454 +919 4 0 64 338 484 454 +920 4 0 359 89 566 338 +921 4 0 489 526 566 64 +922 4 0 448 192 378 373 +923 4 0 350 39 377 33 +924 4 0 369 137 176 168 +925 4 0 377 350 553 39 +926 4 0 325 313 375 341 +927 4 0 340 288 625 282 +928 4 0 342 313 375 325 +929 4 0 524 466 19 20 +930 4 0 425 466 19 524 +931 4 0 348 395 186 202 +932 4 0 610 44 42 45 +933 4 0 409 433 217 223 +934 4 0 217 433 529 223 +935 4 0 582 375 471 115 +936 4 0 434 474 637 369 +937 4 0 382 375 471 582 +938 4 0 98 90 382 375 +939 4 0 382 100 90 98 +940 4 0 123 105 122 85 +941 4 0 122 85 105 80 +942 4 0 43 40 34 38 +943 4 0 369 474 361 136 +944 4 0 469 452 564 460 +945 4 0 46 41 527 457 +946 4 0 415 366 274 323 +947 4 0 191 387 316 438 +948 4 0 191 387 156 316 +949 4 0 434 391 474 369 +950 4 0 502 294 344 465 +951 4 0 502 294 292 293 +952 4 0 476 59 92 79 +953 4 0 306 309 319 336 +954 4 0 528 301 464 285 +955 4 0 301 282 464 285 +956 4 0 208 449 210 379 +957 4 0 210 379 220 208 +958 4 0 551 520 10 467 +959 4 0 359 89 339 106 +960 4 0 110 353 365 116 +961 4 0 353 511 110 365 +962 4 0 118 141 145 152 +963 4 0 34 28 466 29 +964 4 0 621 347 59 54 +965 4 0 59 621 79 347 +966 4 0 342 80 122 302 +967 4 0 369 123 154 342 +968 4 0 123 85 122 342 +969 4 0 122 342 85 80 +970 4 0 450 349 612 482 +971 4 0 564 55 436 413 +972 4 0 40 38 29 34 +973 4 0 606 641 413 436 +974 4 0 28 35 335 33 +975 4 0 34 25 32 29 +976 4 0 487 548 495 479 +977 4 0 187 209 196 348 +978 4 0 461 479 430 495 +979 4 0 311 513 509 186 +980 4 0 395 311 348 186 +981 4 0 187 196 209 444 +982 4 0 485 540 426 373 +983 4 0 21 580 24 447 +984 4 0 412 447 21 562 +985 4 0 412 562 21 446 +986 4 0 447 580 24 10 +987 4 0 46 527 610 413 +988 4 0 229 392 216 222 +989 4 0 323 281 366 274 +990 4 0 281 301 274 323 +991 4 0 599 625 429 282 +992 4 0 608 25 32 34 +993 4 0 372 288 284 340 +994 4 0 227 324 190 308 +995 4 0 373 196 348 187 +996 4 0 425 25 34 29 +997 4 0 628 448 373 591 +998 4 0 591 448 373 398 +999 4 0 477 43 41 527 +1000 4 0 80 71 81 302 +1001 4 0 457 477 41 527 +1002 4 0 647 487 430 479 +1003 4 0 628 373 497 441 +1004 4 0 578 628 441 374 +1005 4 0 410 24 335 350 +1006 4 0 393 311 160 150 +1007 4 0 367 118 137 141 +1008 4 0 343 488 356 396 +1009 4 0 87 72 61 58 +1010 4 0 488 588 356 396 +1011 4 0 476 54 59 347 +1012 4 0 94 353 61 77 +1013 4 0 110 353 87 107 +1014 4 0 251 245 322 201 +1015 4 0 245 179 322 201 +1016 4 0 11 422 486 14 +1017 4 0 287 588 464 528 +1018 4 0 10 467 412 551 +1019 4 0 13 551 412 467 +1020 4 0 371 467 551 13 +1021 4 0 551 10 8 412 +1022 4 0 113 164 361 136 +1023 4 0 425 25 15 26 +1024 4 0 140 348 125 160 +1025 4 0 451 588 528 286 +1026 4 0 180 152 145 141 +1027 4 0 607 16 539 470 +1028 4 0 374 570 400 373 +1029 4 0 373 374 556 400 +1030 4 0 374 373 556 628 +1031 4 0 441 628 578 483 +1032 4 0 497 642 418 629 +1033 4 0 167 89 106 339 +1034 4 0 346 440 390 521 +1035 4 0 369 123 342 375 +1036 4 0 583 382 498 361 +1037 4 0 564 75 72 61 +1038 4 0 564 61 64 75 +1039 4 0 345 517 79 92 +1040 4 0 533 529 223 222 +1041 4 0 498 582 576 375 +1042 4 0 575 376 609 49 +1043 4 0 412 10 8 447 +1044 4 0 561 472 549 468 +1045 4 0 239 322 252 231 +1046 4 0 397 12 4 14 +1047 4 0 367 369 434 576 +1048 4 0 206 313 322 179 +1049 4 0 322 179 313 354 +1050 4 0 12 2 4 7 +1051 4 0 346 638 26 608 +1052 4 0 66 87 57 58 +1053 4 0 72 58 564 61 +1054 4 0 322 207 231 239 +1055 4 0 201 354 322 207 +1056 4 0 239 255 322 201 +1057 4 0 533 402 529 222 +1058 4 0 60 518 564 65 +1059 4 0 11 486 12 14 +1060 4 0 118 168 141 152 +1061 4 0 60 376 564 518 +1062 4 0 576 375 582 115 +1063 4 0 515 34 399 351 +1064 4 0 334 564 64 363 +1065 4 0 311 331 150 305 +1066 4 0 473 538 597 519 +1067 4 0 564 594 575 475 +1068 4 0 36 30 432 410 +1069 4 0 343 396 356 279 +1070 4 0 281 279 356 396 +1071 4 0 281 274 301 356 +1072 4 0 486 7 14 422 +1073 4 0 642 153 585 629 +1074 4 0 153 642 628 629 +1075 4 0 503 447 8 10 +1076 4 0 461 430 620 416 +1077 4 0 493 270 275 280 +1078 4 0 275 493 532 323 +1079 4 0 532 493 282 323 +1080 4 0 461 495 430 416 +1081 4 0 493 532 280 275 +1082 4 0 389 381 47 413 +1083 4 0 49 413 626 527 +1084 4 0 500 189 186 181 +1085 4 0 498 382 582 375 +1086 4 0 410 30 24 377 +1087 4 0 30 410 36 377 +1088 4 0 366 265 279 272 +1089 4 0 608 34 32 31 +1090 4 0 527 40 43 38 +1091 4 0 46 527 41 38 +1092 4 0 43 527 38 41 +1093 4 0 597 639 7 486 +1094 4 0 306 298 336 331 +1095 4 0 11 26 15 543 +1096 4 0 554 11 15 543 +1097 4 0 416 430 620 649 +1098 4 0 291 290 364 327 +1099 4 0 637 498 375 361 +1100 4 0 39 548 33 461 +1101 4 0 422 634 25 543 +1102 4 0 583 582 382 113 +1103 4 0 367 114 118 141 +1104 4 0 473 422 11 554 +1105 4 0 178 197 168 141 +1106 4 0 375 369 123 115 +1107 4 0 91 123 115 375 +1108 4 0 377 350 36 553 +1109 4 0 173 181 516 186 +1110 4 0 110 95 107 87 +1111 4 0 353 107 163 87 +1112 4 0 46 527 42 610 +1113 4 0 500 209 348 202 +1114 4 0 334 61 564 57 +1115 4 0 510 103 140 161 +1116 4 0 160 104 140 133 +1117 4 0 486 11 473 422 +1118 4 0 336 611 331 514 +1119 4 0 576 434 637 369 +1120 4 0 29 466 524 20 +1121 4 0 366 279 265 258 +1122 4 0 366 279 258 274 +1123 4 0 89 484 338 454 +1124 4 0 462 621 568 534 +1125 4 0 133 104 140 103 +1126 4 0 462 534 568 531 +1127 4 0 521 440 390 563 +1128 4 0 383 440 563 390 +1129 4 0 141 154 170 369 +1130 4 0 141 193 369 170 +1131 4 0 173 181 510 516 +1132 4 0 348 510 181 516 +1133 4 0 324 366 276 272 +1134 4 0 415 324 366 323 +1135 4 0 477 527 507 43 +1136 4 0 26 25 440 346 +1137 4 0 430 333 42 479 +1138 4 0 460 452 564 75 +1139 4 0 31 515 32 592 +1140 4 0 181 189 187 500 +1141 4 0 389 527 413 47 +1142 4 0 413 389 626 527 +1143 4 0 376 590 49 575 +1144 4 0 331 611 185 508 +1145 4 0 223 392 407 219 +1146 4 0 223 233 392 219 +1147 4 0 538 648 597 519 +1148 4 0 597 648 538 486 +1149 4 0 557 537 568 499 +1150 4 0 553 39 461 416 +1151 4 0 290 528 451 287 +1152 4 0 554 453 332 560 +1153 4 0 601 467 458 9 +1154 4 0 623 525 535 566 +1155 4 0 566 525 535 526 +1156 4 0 378 106 431 418 +1157 4 0 53 496 352 347 +1158 4 0 564 300 419 72 +1159 4 0 564 452 300 72 +1160 4 0 2 6 7 486 +1161 4 0 421 451 528 286 +1162 4 0 451 528 588 287 +1163 4 0 409 595 433 491 +1164 4 0 79 621 78 401 +1165 4 0 401 621 78 555 +1166 4 0 78 537 555 621 +1167 4 0 599 340 282 301 +1168 4 0 493 599 282 301 +1169 4 0 430 620 42 333 +1170 4 0 565 498 112 637 +1171 4 0 583 498 112 565 +1172 4 0 599 429 536 282 +1173 4 0 599 625 459 429 +1174 4 0 543 554 332 15 +1175 4 0 474 112 637 565 +1176 4 0 364 290 528 327 +1177 4 0 548 461 479 333 +1178 4 0 461 333 430 479 +1179 4 0 383 390 346 440 +1180 4 0 65 60 64 564 +1181 4 0 65 64 75 564 +1182 4 0 383 638 346 390 +1183 4 0 380 468 614 549 +1184 4 0 532 282 276 323 +1185 4 0 157 331 504 150 +1186 4 0 89 454 338 339 +1187 4 0 167 454 89 339 +1188 4 0 8 5 10 551 +1189 4 0 5 520 10 551 +1190 4 0 492 626 545 389 +1191 4 0 389 626 545 469 +1192 4 0 37 33 35 29 +1193 4 0 615 568 499 557 +1194 4 0 500 186 480 202 +1195 4 0 54 56 53 496 +1196 4 0 294 295 291 385 +1197 4 0 295 291 385 327 +1198 4 0 295 294 292 385 +1199 4 0 474 637 361 565 +1200 4 0 497 373 426 540 +1201 4 0 40 29 28 34 +1202 4 0 535 525 581 526 +1203 4 0 328 92 79 517 +1204 4 0 496 56 352 604 +1205 4 0 459 536 646 493 +1206 4 0 459 429 624 536 +1207 4 0 493 536 280 532 +1208 4 0 25 346 26 608 +1209 4 0 351 399 41 38 +1210 4 0 43 41 38 351 +1211 4 0 527 413 47 606 +1212 4 0 308 252 322 231 +1213 4 0 308 255 322 252 +1214 4 0 256 231 252 308 +1215 4 0 256 308 259 247 +1216 4 0 21 30 24 410 +1217 4 0 21 30 562 24 +1218 4 0 315 621 555 568 +1219 4 0 217 219 223 407 +1220 4 0 225 223 219 233 +1221 4 0 407 217 529 223 +1222 4 0 381 452 300 564 +1223 4 0 595 635 433 491 +1224 4 0 414 385 291 327 +1225 4 0 416 39 461 495 +1226 4 0 461 39 548 495 +1227 4 0 461 548 479 495 +1228 4 0 301 282 281 464 +1229 4 0 301 282 285 340 +1230 4 0 315 621 568 462 +1231 4 0 372 289 288 285 +1232 4 0 289 288 285 414 +1233 4 0 431 153 106 378 +1234 4 0 55 641 589 436 +1235 4 0 651 572 638 608 +1236 4 0 564 452 72 75 +1237 4 0 573 534 567 613 +1238 4 0 567 645 600 534 +1239 4 0 499 568 577 537 +1240 4 0 414 327 291 364 +1241 4 0 561 549 614 468 +1242 4 0 338 489 566 64 +1243 4 0 89 484 489 338 +1244 4 0 385 294 465 344 +1245 4 0 445 196 444 209 +1246 4 0 209 550 444 427 +1247 4 0 490 14 11 12 +1248 4 0 490 18 14 12 +1249 4 0 597 648 486 7 +1250 4 0 486 639 7 422 +1251 4 0 639 473 597 631 +1252 4 0 529 491 616 533 +1253 4 0 435 320 125 373 +1254 4 0 616 491 529 541 +1255 4 0 497 628 642 629 +1256 4 0 46 52 413 602 +1257 4 0 623 359 566 338 +1258 4 0 497 506 629 418 +1259 4 0 99 359 623 338 +1260 4 0 65 64 454 75 +1261 4 0 209 617 550 427 +1262 4 0 86 328 144 128 +1263 4 0 570 187 374 368 +1264 4 0 403 86 633 328 +1265 4 0 601 522 458 523 +1266 4 0 604 352 472 56 +1267 4 0 273 312 319 324 +1268 4 0 380 614 63 549 +1269 4 0 561 549 63 614 +1270 4 0 623 525 566 359 +1271 4 0 359 525 566 526 +1272 4 0 566 89 526 489 +1273 4 0 113 382 358 471 +1274 4 0 582 471 382 113 +1275 4 0 523 467 458 601 +1276 4 0 268 308 260 263 +1277 4 0 374 628 556 578 +1278 4 0 498 582 382 583 +1279 4 0 586 645 534 557 +1280 4 0 361 176 369 136 +1281 4 0 277 356 274 279 +1282 4 0 576 637 375 369 +1283 4 0 637 375 369 361 +1284 4 0 373 556 569 400 +1285 4 0 556 373 569 628 +1286 4 0 447 562 24 21 +1287 4 0 47 492 527 507 +1288 4 0 495 39 548 487 +1289 4 0 572 608 651 650 +1290 4 0 541 619 542 574 +1291 4 0 27 562 21 30 +1292 4 0 21 446 562 27 +1293 4 0 517 328 614 79 +1294 4 0 545 530 622 575 +1295 4 0 522 371 523 558 +1296 4 0 523 371 520 558 +1297 4 0 471 91 115 375 +1298 4 0 578 127 628 556 +1299 4 0 127 153 628 556 +1300 4 0 641 413 55 52 +1301 4 0 55 564 436 58 +1302 4 0 564 334 57 594 +1303 4 0 55 641 436 413 +1304 4 0 575 413 49 594 +1305 4 0 15 17 596 560 +1306 4 0 521 440 563 571 +1307 4 0 632 581 62 526 +1308 4 0 285 372 301 340 +1309 4 0 290 451 528 421 +1310 4 0 326 57 564 58 +1311 4 0 205 212 241 204 +1312 4 0 564 452 469 381 +1313 4 0 239 322 207 201 +1314 4 0 223 392 529 407 +1315 4 0 381 564 413 469 +1316 4 0 395 513 311 186 +1317 4 0 389 469 413 626 +1318 4 0 136 361 583 565 +1319 4 0 586 645 567 534 +1320 4 0 32 25 608 346 +1321 4 0 369 367 137 141 +1322 4 0 469 575 545 622 +1323 4 0 593 543 634 422 +1324 4 0 373 569 628 591 +1325 4 0 556 569 153 628 +1326 4 0 196 187 373 570 +1327 4 0 167 454 339 155 +1328 4 0 590 626 575 530 +1329 4 0 536 493 282 532 +1330 4 0 133 140 160 510 +1331 4 0 376 363 64 564 +1332 4 0 209 427 444 587 +1333 4 0 571 440 563 383 +1334 4 0 498 375 576 637 +1335 4 0 531 534 568 579 +1336 4 0 534 568 557 621 +1337 4 0 218 392 643 238 +1338 4 0 568 555 577 537 +1339 4 0 475 609 363 49 +1340 4 0 363 609 475 564 +1341 4 0 393 311 150 305 +1342 4 0 19 425 17 596 +1343 4 0 596 17 603 560 +1344 4 0 522 428 371 558 +1345 4 0 127 628 497 483 +1346 4 0 492 48 545 626 +1347 4 0 21 607 24 580 +1348 4 0 132 117 318 128 +1349 4 0 633 132 547 142 +1350 4 0 437 381 419 413 +1351 4 0 419 381 437 300 +1352 4 0 173 181 186 171 +1353 4 0 405 613 600 534 +1354 4 0 632 526 62 64 +1355 4 0 489 484 64 338 +1356 4 0 600 54 53 621 +1357 4 0 29 20 28 466 +1358 4 0 20 28 466 443 +1359 4 0 49 48 626 590 +1360 4 0 63 345 614 380 +1361 4 0 584 345 63 380 +1362 4 0 470 607 559 478 +1363 4 0 28 23 22 20 +1364 4 0 478 23 22 28 +1365 4 0 473 422 554 631 +1366 4 0 555 537 568 621 +1367 4 0 18 490 14 439 +1368 4 0 596 17 19 603 +1369 4 0 571 440 18 521 +1370 4 0 542 491 616 541 +1371 4 0 534 568 615 557 +1372 4 0 534 568 579 615 +1373 4 0 392 222 229 238 +1374 4 0 626 48 530 590 +1375 4 0 238 406 229 423 +1376 4 0 629 585 642 418 +1377 4 0 418 506 629 378 +1378 4 0 378 431 629 418 +1379 4 0 153 448 628 591 +1380 4 0 591 569 628 153 +1381 4 0 550 209 500 627 +1382 4 0 515 31 32 34 +1383 4 0 209 627 550 617 +1384 4 0 569 556 153 400 +1385 4 0 645 621 557 54 +1386 4 0 529 491 533 223 +1387 4 0 601 1 458 522 +1388 4 0 522 601 1 3 +1389 4 0 359 339 99 106 +1390 4 0 338 99 359 339 +1391 4 0 49 575 626 413 +1392 4 0 473 597 631 453 +1393 4 0 605 564 518 460 +1394 4 0 222 392 402 529 +1395 4 0 113 382 583 361 +1396 4 0 33 335 28 23 +1397 4 0 370 52 594 46 +1398 4 0 408 505 580 607 +1399 4 0 413 640 602 641 +1400 4 0 630 376 564 609 +1401 4 0 49 376 609 363 +1402 4 0 363 376 609 564 +1403 4 0 393 456 311 305 +1404 4 0 218 221 386 643 +1405 4 0 643 386 423 221 +1406 4 0 141 123 369 367 +1407 4 0 498 382 375 361 +1408 4 0 474 637 369 361 +1409 4 0 558 371 520 551 +1410 4 0 558 428 371 551 +1411 4 0 374 441 411 373 +1412 4 0 422 25 26 543 +1413 4 0 25 17 15 634 +1414 4 0 606 44 610 45 +1415 4 0 367 115 369 576 +1416 4 0 367 576 546 115 +1417 4 0 636 573 567 613 +1418 4 0 615 51 579 573 +1419 4 0 50 51 615 636 +1420 4 0 55 413 564 52 +1421 4 0 594 52 413 46 +1422 4 0 564 326 52 57 +1423 4 0 367 434 546 576 +1424 4 0 208 449 379 445 +1425 4 0 379 445 544 208 +1426 4 0 26 439 440 25 +1427 4 0 622 575 605 469 +1428 4 0 636 586 567 573 +1429 4 0 573 586 567 534 +1430 4 0 599 625 340 283 +1431 4 0 605 630 518 564 +1432 4 0 171 510 181 161 +1433 4 0 32 29 38 34 +1434 4 0 402 216 392 222 +1435 4 0 223 222 392 238 +1436 4 0 389 492 527 47 +1437 4 0 389 492 626 527 +1438 4 0 577 555 78 537 +1439 4 0 315 621 401 555 +1440 4 0 15 598 634 560 +1441 4 0 634 17 15 560 +1442 4 0 481 142 328 633 +1443 4 0 128 328 144 138 +1444 4 0 413 610 640 606 +1445 4 0 640 606 610 45 +1446 4 0 379 449 444 445 +1447 4 0 187 449 196 444 +1448 4 0 445 449 444 196 +1449 4 0 605 564 460 469 +1450 4 0 575 564 605 469 +1451 4 0 541 200 619 574 +1452 4 0 564 436 419 413 +1453 4 0 517 482 63 614 +1454 4 0 154 369 141 123 +1455 4 0 583 498 565 361 +1456 4 0 498 361 637 565 +1457 4 0 622 530 630 575 +1458 4 0 21 30 432 27 +1459 4 0 173 510 160 516 +1460 4 0 311 160 348 516 +1461 4 0 485 140 540 373 +1462 4 0 21 505 580 447 +1463 4 0 490 26 439 571 +1464 4 0 379 544 220 208 +1465 4 0 348 516 181 186 +1466 4 0 186 509 311 516 +1467 4 0 209 202 627 617 +1468 4 0 433 635 529 491 +1469 4 0 430 42 620 44 +1470 4 0 649 430 620 44 +1471 4 0 529 635 541 491 +1472 4 0 404 24 410 21 +1473 4 0 404 410 24 335 +1474 4 0 89 338 359 339 +1475 4 0 450 328 482 517 +1476 4 0 517 328 482 614 +1477 4 0 78 59 537 621 +1478 4 0 588 396 281 356 +1479 4 0 286 488 588 356 +1480 4 0 424 543 593 422 +1481 4 0 463 607 408 16 +1482 4 0 389 381 413 469 +1483 4 0 413 469 575 626 +1484 4 0 626 469 575 545 +1485 4 0 554 11 543 422 +1486 4 0 459 624 646 536 +1487 4 0 332 543 593 424 +1488 4 0 631 554 424 422 +1489 4 0 153 431 629 378 +1490 4 0 545 48 530 626 +1491 4 0 626 530 545 575 +1492 4 0 59 621 78 79 +1493 4 0 160 510 348 516 +1494 4 0 626 590 575 49 +1495 4 0 576 434 112 637 +1496 4 0 498 576 112 637 +1497 4 0 346 651 638 608 +1498 4 0 13 442 412 362 +1499 4 0 13 467 412 442 +1500 4 0 132 142 633 128 +1501 4 0 184 180 172 170 +1502 4 0 631 332 424 554 +1503 4 0 531 573 579 51 +1504 4 0 521 571 563 18 +1505 4 0 599 625 282 340 +1506 4 0 622 630 605 575 +1507 4 0 562 442 362 412 +1508 4 0 193 180 170 141 +1509 4 0 50 644 636 615 +1510 4 0 443 466 20 19 +1511 4 0 616 542 533 491 +1512 4 0 413 594 564 52 +1513 4 0 621 53 600 405 +1514 4 0 362 562 446 27 +1515 4 0 403 547 321 481 +1516 4 0 403 481 321 329 +1517 4 0 562 442 412 10 +1518 4 0 493 459 536 599 +1519 4 0 493 599 536 282 +1520 4 0 450 86 328 517 +1521 4 0 413 602 610 46 +1522 4 0 29 23 28 20 +1523 4 0 223 409 433 491 +1524 4 0 621 59 537 54 +1525 4 0 13 362 412 446 +1526 4 0 439 422 11 14 +1527 4 0 639 473 631 422 +1528 4 0 450 612 584 517 +1529 4 0 450 482 612 517 +1530 4 0 413 641 602 52 +1531 4 0 447 10 24 562 +1532 4 0 531 573 534 579 +1533 4 0 380 345 468 604 +1534 4 0 587 427 444 618 +1535 4 0 613 567 600 534 +1536 4 0 218 386 238 643 +1537 4 0 643 238 423 386 +1538 4 0 347 496 352 604 +1539 4 0 63 345 517 614 +1540 4 0 584 612 63 517 +1541 4 0 629 431 585 418 +1542 4 0 153 431 585 629 +1543 4 0 463 539 478 607 +1544 4 0 463 539 607 16 +1545 4 0 564 609 475 575 +1546 4 0 533 529 402 616 +1547 4 0 376 630 564 518 +1548 4 0 645 54 600 621 +1549 4 0 380 468 472 604 +1550 4 0 604 468 472 352 +1551 4 0 380 468 549 472 +1552 4 0 570 187 373 374 +1553 4 0 606 413 641 640 +1554 4 0 413 610 602 640 +1555 4 0 458 467 13 9 +1556 4 0 467 458 13 371 +1557 4 0 11 422 26 543 +1558 4 0 25 17 425 15 +1559 4 0 646 536 280 493 +1560 4 0 646 624 280 536 +1561 4 0 647 430 44 42 +1562 4 0 618 544 220 379 +1563 4 0 648 6 486 7 +1564 4 0 648 6 538 486 +1565 4 0 403 633 547 481 +1566 4 0 403 328 633 481 +1567 4 0 483 127 628 578 +1568 4 0 486 7 12 14 +1569 4 0 53 56 352 496 +1570 4 0 340 288 284 625 +1571 4 0 283 340 284 625 +1572 4 0 561 352 472 468 +1573 4 0 86 450 328 403 +1574 4 0 329 403 481 328 +1575 4 0 455 288 284 372 +1576 4 0 501 288 284 455 +1577 4 0 376 530 575 630 +1578 4 0 630 376 609 575 +1579 4 0 430 479 42 647 +1580 4 0 621 405 600 534 +1581 4 0 22 28 20 443 +1582 4 0 643 238 229 423 +1583 4 0 481 633 547 142 +1584 4 0 558 428 551 652 +1585 4 0 509 611 331 508 +1586 4 0 513 514 331 611 +1587 4 0 509 513 331 611 +1588 4 0 601 9 1 3 +1589 4 0 289 288 344 501 +1590 4 0 515 32 399 34 +1591 4 0 403 321 349 329 +1592 4 0 392 229 643 238 +1593 4 0 618 445 544 379 +1594 4 0 618 587 544 445 +1595 4 0 531 613 534 573 +1596 4 0 629 153 448 628 +1597 4 0 538 473 597 486 +1598 4 0 597 473 639 486 +1599 4 0 650 31 608 346 +1600 4 0 607 505 580 21 +1601 4 0 288 455 289 372 +1602 4 0 289 455 288 501 +1603 4 0 376 530 590 575 +1604 4 0 49 594 475 575 +1605 4 0 356 279 281 274 +1606 4 0 550 209 444 500 +1607 4 0 362 412 446 562 +1608 4 0 529 433 491 223 +1609 4 0 455 372 284 283 +1610 4 0 465 501 455 289 +1611 4 0 465 289 344 501 +1612 4 0 445 209 444 587 +1613 4 0 153 642 127 628 +1614 4 0 294 385 291 414 +1615 4 0 283 625 459 599 +1616 4 0 613 531 51 573 +1617 4 0 636 573 613 51 +1618 4 0 557 621 568 537 +1619 4 0 558 551 520 5 +1620 4 0 500 209 202 627 +1621 4 0 635 200 541 574 +1622 4 0 595 200 635 574 +1623 4 0 558 652 551 5 +1624 4 0 534 579 573 615 +1625 4 0 605 575 630 564 +1626 4 0 31 346 32 608 +1627 4 0 631 424 639 422 +1628 4 0 383 346 638 26 +1629 4 0 469 575 564 413 +1630 4 0 15 560 332 598 +1631 4 0 15 554 332 560 +1632 4 0 586 557 534 615 +1633 4 0 573 586 534 615 +1634 4 0 332 543 598 593 +1635 4 0 543 332 598 15 +1636 4 0 609 575 564 630 +1637 4 0 554 631 332 453 +1638 4 0 424 554 543 422 +1639 4 0 608 346 651 650 +1640 4 0 487 495 430 479 +1641 4 0 645 621 534 557 +1642 4 0 645 621 600 534 +1643 4 0 542 491 541 574 +1644 4 0 541 635 574 491 +1645 4 0 636 644 586 573 +1646 4 0 573 586 615 644 +1647 4 0 543 634 598 593 +1648 4 0 497 127 642 628 +1649 4 0 598 543 15 634 +1650 4 0 25 15 543 634 +1651 4 0 473 519 597 453 +1652 4 0 595 574 635 491 +1653 4 0 636 51 615 573 +1654 4 0 644 573 636 615 +$EndElements +$ElementData +1 +"color" +1 +0.0 +3 +0 +1 +1654 +1 7.56199 +2 4.86806 +3 4.40144 +4 6.42934 +5 4.22059 +6 5.73014 +7 6.38728 +8 6.65278 +9 6.11566 +10 8.59831 +11 4.59846 +12 3.75402 +13 4.81655 +14 5.303 +15 4.23688 +16 4.44352 +17 9.61146 +18 4.02007 +19 6.55381 +20 4.32183 +21 3.77651 +22 4.28126 +23 4.67035 +24 4.25302 +25 3.24949 +26 3.81682 +27 3.6786 +28 5.26567 +29 5.75883 +30 4.40013 +31 4.8604 +32 3.88159 +33 3.62912 +34 6.09732 +35 6.23606 +36 6.81931 +37 3.98474 +38 5.09313 +39 7.92162 +40 5.91342 +41 5.89822 +42 7.79576 +43 3.26766 +44 6.40478 +45 3.30998 +46 5.75804 +47 4.44341 +48 5.56712 +49 7.92901 +50 7.32341 +51 4.11488 +52 7.27876 +53 4.46523 +54 4.41017 +55 4.24074 +56 5.18865 +57 3.67411 +58 3.93323 +59 6.27803 +60 5.7046 +61 5.43246 +62 6.62422 +63 6.87791 +64 4.8315 +65 4.41484 +66 3.44597 +67 4.80585 +68 4.76576 +69 5.09151 +70 3.90176 +71 3.98978 +72 7.05842 +73 5.79771 +74 5.72113 +75 5.39406 +76 8.36837 +77 6.57885 +78 3.81664 +79 5.04602 +80 5.13045 +81 4.17786 +82 4.12193 +83 5.498 +84 3.9477 +85 4.17729 +86 4.53085 +87 4.87674 +88 5.63865 +89 4.91132 +90 5.42233 +91 7.2101 +92 6.62552 +93 5.99626 +94 5.99827 +95 4.64279 +96 4.40763 +97 7.74874 +98 4.60244 +99 4.55322 +100 3.87632 +101 4.43066 +102 3.5908 +103 4.4961 +104 4.6942 +105 6.85876 +106 6.09827 +107 5.34771 +108 3.88554 +109 4.99917 +110 5.07909 +111 5.16529 +112 6.2445 +113 4.05386 +114 4.0937 +115 4.62717 +116 4.31849 +117 3.26285 +118 3.35407 +119 3.68025 +120 5.5668 +121 4.22251 +122 4.99967 +123 4.02172 +124 7.95474 +125 6.88951 +126 5.11647 +127 3.62751 +128 3.75947 +129 5.71937 +130 4.65378 +131 4.22097 +132 3.54665 +133 4.0164 +134 4.14403 +135 5.88228 +136 3.88365 +137 4.9027 +138 3.88649 +139 3.94684 +140 5.61741 +141 4.86852 +142 4.25794 +143 7.6941 +144 4.73617 +145 3.12373 +146 4.88928 +147 3.62576 +148 4.16485 +149 3.9426 +150 3.46852 +151 6.77747 +152 5.33702 +153 6.56503 +154 5.80932 +155 6.15413 +156 6.85355 +157 4.14906 +158 6.14933 +159 6.69641 +160 3.64734 +161 9.61926 +162 4.84044 +163 6.90865 +164 3.44809 +165 7.79131 +166 4.2801 +167 3.52051 +168 5.45391 +169 3.39718 +170 4.71838 +171 3.97902 +172 6.18658 +173 4.17284 +174 3.92603 +175 6.61929 +176 4.47741 +177 5.4168 +178 4.66072 +179 6.78272 +180 8.92575 +181 3.81346 +182 3.82779 +183 3.59616 +184 4.4729 +185 4.12509 +186 9.13405 +187 4.3469 +188 4.17304 +189 3.37722 +190 4.22285 +191 3.89981 +192 3.56114 +193 5.07249 +194 5.73119 +195 3.31977 +196 7.91262 +197 4.91172 +198 4.3087 +199 4.15402 +200 7.6821 +201 4.41955 +202 4.64581 +203 4.16326 +204 7.51723 +205 6.23256 +206 4.63327 +207 4.85318 +208 6.48807 +209 3.61821 +210 5.09043 +211 8.53276 +212 6.52094 +213 3.90421 +214 4.42601 +215 3.83625 +216 5.54714 +217 3.51603 +218 3.84227 +219 5.7805 +220 5.82631 +221 4.20829 +222 5.28021 +223 4.00498 +224 6.02503 +225 5.06898 +226 5.05237 +227 4.69681 +228 4.59421 +229 4.21961 +230 4.26009 +231 5.25661 +232 6.12045 +233 4.26478 +234 3.42011 +235 3.96254 +236 5.39782 +237 5.34452 +238 5.57074 +239 3.58786 +240 5.48832 +241 5.04805 +242 6.99507 +243 4.86669 +244 8.67723 +245 4.42583 +246 6.08779 +247 8.30081 +248 4.11458 +249 7.33372 +250 4.37632 +251 6.55974 +252 4.06411 +253 7.65217 +254 4.98446 +255 7.00166 +256 9.18261 +257 3.97417 +258 3.76504 +259 4.45173 +260 3.78705 +261 8.85178 +262 5.99438 +263 3.68369 +264 4.64732 +265 5.79147 +266 6.364 +267 5.03453 +268 4.96944 +269 4.75356 +270 3.20622 +271 4.24018 +272 4.41709 +273 4.21315 +274 4.38612 +275 6.51163 +276 5.01322 +277 5.46653 +278 3.97587 +279 6.44458 +280 4.97667 +281 5.55967 +282 5.85158 +283 5.0027 +284 3.48534 +285 6.58618 +286 4.80285 +287 5.94949 +288 4.82903 +289 7.5367 +290 5.70127 +291 7.09932 +292 5.78603 +293 5.97275 +294 3.8847 +295 7.18803 +296 4.24715 +297 6.96264 +298 7.0952 +299 4.63648 +300 6.55609 +301 5.16808 +302 5.24241 +303 3.54707 +304 4.3924 +305 4.0213 +306 4.62658 +307 4.81065 +308 4.56642 +309 6.50736 +310 4.75308 +311 3.8215 +312 3.41325 +313 4.08294 +314 4.91393 +315 5.30757 +316 7.02954 +317 5.24187 +318 4.13738 +319 6.58547 +320 3.70239 +321 3.67817 +322 4.58162 +323 5.24492 +324 4.86733 +325 4.91221 +326 4.2757 +327 5.39939 +328 4.61598 +329 8.42673 +330 6.14168 +331 4.57608 +332 3.81451 +333 4.29124 +334 4.12792 +335 5.02872 +336 5.23399 +337 3.38677 +338 4.50817 +339 5.28311 +340 5.64442 +341 4.71327 +342 6.09192 +343 4.17098 +344 7.35127 +345 5.55052 +346 8.62264 +347 7.92427 +348 4.62414 +349 5.61806 +350 5.34776 +351 6.86714 +352 4.07043 +353 3.76518 +354 3.52133 +355 4.0364 +356 4.23061 +357 5.51497 +358 5.34338 +359 5.2446 +360 3.66377 +361 3.61536 +362 4.93218 +363 5.91732 +364 3.99037 +365 6.86673 +366 4.57754 +367 4.54417 +368 3.49705 +369 3.68222 +370 4.05441 +371 3.28484 +372 3.86728 +373 6.47469 +374 3.8287 +375 4.21948 +376 6.50072 +377 5.2599 +378 5.46621 +379 3.90163 +380 8.20664 +381 5.20216 +382 5.3226 +383 4.03878 +384 8.93219 +385 6.79859 +386 5.0444 +387 4.38992 +388 6.97679 +389 3.69486 +390 3.64051 +391 3.67985 +392 6.23422 +393 3.30838 +394 7.50667 +395 3.94216 +396 6.5134 +397 8.60865 +398 4.39139 +399 3.46463 +400 3.90001 +401 4.26802 +402 3.71403 +403 3.59913 +404 3.15595 +405 4.92885 +406 9.80662 +407 3.63884 +408 3.80748 +409 5.15094 +410 6.35325 +411 4.20196 +412 5.86833 +413 5.91247 +414 3.313 +415 3.37645 +416 4.89339 +417 5.19552 +418 6.53485 +419 7.98558 +420 3.6091 +421 4.05488 +422 4.29978 +423 4.68265 +424 8.03386 +425 5.59842 +426 4.70185 +427 3.61697 +428 5.69205 +429 7.16982 +430 4.13106 +431 3.56492 +432 4.22082 +433 4.55629 +434 4.58142 +435 5.53457 +436 6.93426 +437 4.80377 +438 3.84526 +439 3.94317 +440 3.45505 +441 5.16289 +442 3.25289 +443 3.95152 +444 5.40892 +445 6.95209 +446 4.15315 +447 5.02186 +448 4.01812 +449 3.96462 +450 7.14857 +451 4.97123 +452 4.79327 +453 4.80934 +454 7.58936 +455 4.07601 +456 4.83387 +457 4.20561 +458 4.19693 +459 4.28828 +460 6.64926 +461 6.10328 +462 5.14523 +463 3.29956 +464 7.82612 +465 6.51338 +466 5.14228 +467 6.36966 +468 4.00039 +469 5.25401 +470 4.90217 +471 3.91685 +472 4.04775 +473 3.71452 +474 4.00893 +475 6.15397 +476 4.73995 +477 4.49103 +478 6.01817 +479 4.51129 +480 4.45673 +481 4.53029 +482 4.39765 +483 4.84946 +484 4.41482 +485 5.22789 +486 4.83751 +487 4.52841 +488 4.37907 +489 4.53931 +490 3.94812 +491 5.60107 +492 7.82411 +493 6.10887 +494 3.61105 +495 6.22222 +496 5.87689 +497 4.37764 +498 5.74756 +499 5.41576 +500 3.94004 +501 5.49027 +502 4.62278 +503 5.90077 +504 3.72543 +505 8.58284 +506 9.99379 +507 3.93429 +508 7.00354 +509 3.34162 +510 6.26251 +511 4.5708 +512 4.61934 +513 6.10199 +514 7.60203 +515 3.49142 +516 6.17078 +517 5.25425 +518 6.30042 +519 5.72046 +520 4.47283 +521 4.83221 +522 4.41013 +523 5.97733 +524 3.99931 +525 4.76894 +526 3.74452 +527 6.2368 +528 4.09343 +529 6.26363 +530 6.83661 +531 3.96425 +532 3.43579 +533 5.77657 +534 5.34581 +535 4.68041 +536 4.37814 +537 5.99737 +538 5.3648 +539 5.4205 +540 4.22935 +541 5.82056 +542 3.98684 +543 3.28936 +544 4.1958 +545 4.33791 +546 4.85201 +547 5.22988 +548 6.51603 +549 4.38544 +550 4.03691 +551 4.28065 +552 7.54771 +553 5.3477 +554 3.98013 +555 3.65612 +556 3.6305 +557 4.96827 +558 7.0639 +559 5.12306 +560 5.26116 +561 3.98468 +562 4.06433 +563 4.43174 +564 9.65465 +565 4.48661 +566 7.06711 +567 6.01908 +568 5.78751 +569 6.07332 +570 8.58829 +571 7.11434 +572 3.46196 +573 5.46102 +574 6.3086 +575 5.34819 +576 6.91082 +577 4.47437 +578 7.81942 +579 6.82906 +580 4.72318 +581 4.06215 +582 9.60519 +583 5.3436 +584 4.7691 +585 4.475 +586 5.84693 +587 5.8161 +588 4.01326 +589 8.52049 +590 6.06203 +591 3.94 +592 6.42148 +593 6.28834 +594 4.88767 +595 7.62703 +596 7.56987 +597 5.54109 +598 4.11926 +599 6.37613 +600 4.92981 +601 4.80206 +602 3.26213 +603 6.37042 +604 5.17572 +605 3.76555 +606 5.26092 +607 4.19725 +608 3.19057 +609 5.88572 +610 5.22575 +611 3.782 +612 4.38116 +613 8.53952 +614 4.30787 +615 4.10562 +616 7.62857 +617 5.65392 +618 5.96086 +619 4.91053 +620 6.14863 +621 5.91276 +622 4.27409 +623 5.55369 +624 4.8645 +625 4.77293 +626 3.55957 +627 4.11882 +628 3.68402 +629 6.55336 +630 5.93665 +631 6.29134 +632 5.06148 +633 6.32722 +634 3.56814 +635 4.97852 +636 5.319 +637 7.67988 +638 4.9724 +639 3.58948 +640 3.2273 +641 4.94275 +642 6.132 +643 4.23477 +644 3.8824 +645 6.47761 +646 5.83872 +647 6.52367 +648 9.09261 +649 4.02275 +650 4.5423 +651 3.77518 +652 9.34733 +653 4.29857 +654 3.53165 +655 3.69875 +656 8.91855 +657 8.27777 +658 4.2927 +659 5.44146 +660 4.88306 +661 4.61662 +662 4.66585 +663 4.08773 +664 5.47614 +665 4.82537 +666 5.34588 +667 5.09433 +668 4.74203 +669 4.80349 +670 5.17033 +671 5.55982 +672 5.85245 +673 8.50255 +674 5.05679 +675 8.2833 +676 4.20019 +677 6.65706 +678 5.50201 +679 3.83497 +680 8.04853 +681 3.98407 +682 4.14575 +683 4.40359 +684 3.83137 +685 7.5115 +686 4.55691 +687 5.02113 +688 4.10109 +689 3.2165 +690 6.76792 +691 7.39527 +692 5.09019 +693 4.66208 +694 4.89628 +695 3.82454 +696 7.89338 +697 4.34543 +698 4.53367 +699 4.2245 +700 7.97378 +701 5.36364 +702 5.48083 +703 5.18437 +704 7.54515 +705 8.01303 +706 6.9711 +707 5.10957 +708 4.65648 +709 4.17603 +710 3.95182 +711 4.30453 +712 4.83791 +713 5.75603 +714 6.26297 +715 4.26312 +716 4.92191 +717 6.49723 +718 5.39117 +719 7.63936 +720 3.8902 +721 5.26165 +722 3.56636 +723 5.80111 +724 8.11139 +725 6.99287 +726 6.0905 +727 4.48145 +728 6.29626 +729 6.41609 +730 4.82834 +731 4.30295 +732 5.95249 +733 9.1162 +734 7.17952 +735 4.41636 +736 7.00516 +737 5.38428 +738 4.57018 +739 5.16323 +740 6.21328 +741 3.84546 +742 8.92755 +743 4.95277 +744 5.60229 +745 4.74588 +746 4.39131 +747 3.53583 +748 4.71464 +749 3.85774 +750 4.32924 +751 4.21807 +752 5.56949 +753 3.92575 +754 4.08047 +755 4.19341 +756 5.43269 +757 5.08675 +758 7.55608 +759 4.60229 +760 5.26588 +761 6.53396 +762 6.09301 +763 8.49182 +764 3.65278 +765 3.7977 +766 4.72003 +767 5.07267 +768 5.39706 +769 5.74691 +770 7.17011 +771 4.60288 +772 6.53685 +773 5.03197 +774 4.75913 +775 5.21044 +776 8.20214 +777 5.1994 +778 5.72262 +779 5.56165 +780 5.11548 +781 4.91619 +782 4.4872 +783 5.68936 +784 4.47124 +785 5.13239 +786 3.56721 +787 6.21762 +788 7.03673 +789 4.75488 +790 6.58105 +791 6.02163 +792 4.0573 +793 5.61253 +794 4.57518 +795 6.37637 +796 4.44356 +797 4.71151 +798 7.569 +799 4.14096 +800 5.59666 +801 4.97895 +802 3.58641 +803 3.31542 +804 5.39692 +805 4.83649 +806 3.97031 +807 5.44832 +808 4.02433 +809 3.60805 +810 5.34786 +811 3.58587 +812 6.69862 +813 3.32895 +814 4.09119 +815 4.58371 +816 3.80674 +817 6.44114 +818 6.223 +819 4.0441 +820 4.80123 +821 4.30222 +822 6.44328 +823 5.35506 +824 6.92359 +825 3.89947 +826 6.49231 +827 4.93294 +828 4.30558 +829 6.36489 +830 6.66548 +831 4.33778 +832 4.17984 +833 5.47755 +834 6.30491 +835 4.8866 +836 3.97457 +837 5.46085 +838 9.49042 +839 5.90533 +840 4.86468 +841 6.77968 +842 4.50722 +843 6.47377 +844 6.71684 +845 7.28311 +846 4.96895 +847 4.62845 +848 4.76509 +849 4.94072 +850 6.06047 +851 5.03461 +852 4.02971 +853 6.54434 +854 6.22769 +855 4.93337 +856 3.68803 +857 3.53863 +858 3.91408 +859 5.65137 +860 7.37176 +861 4.59552 +862 6.93334 +863 3.44661 +864 6.33348 +865 5.02479 +866 5.35196 +867 4.49256 +868 4.90908 +869 5.13244 +870 6.53011 +871 6.74559 +872 6.30754 +873 4.22522 +874 5.22566 +875 4.48669 +876 6.19697 +877 5.32891 +878 5.90513 +879 5.26841 +880 4.69307 +881 6.53259 +882 5.37303 +883 4.84613 +884 6.84862 +885 8.57067 +886 4.51242 +887 4.09543 +888 3.96732 +889 3.54212 +890 7.13459 +891 3.96056 +892 3.53356 +893 7.88643 +894 3.71017 +895 4.50089 +896 6.13237 +897 9.12911 +898 5.99732 +899 4.20221 +900 5.07845 +901 7.39265 +902 3.4358 +903 6.92631 +904 6.19262 +905 8.37263 +906 3.90019 +907 5.27365 +908 8.43827 +909 4.30468 +910 7.89174 +911 4.55601 +912 5.99339 +913 3.9157 +914 6.4819 +915 5.12264 +916 4.56214 +917 4.68284 +918 3.62525 +919 5.50492 +920 3.3911 +921 5.44747 +922 5.1212 +923 3.91631 +924 4.09731 +925 3.90953 +926 3.24567 +927 3.84614 +928 3.16043 +929 5.57228 +930 5.27177 +931 4.70165 +932 6.21956 +933 6.82471 +934 4.75076 +935 5.36529 +936 7.32308 +937 5.56332 +938 4.4607 +939 4.55218 +940 4.41271 +941 4.16343 +942 3.60628 +943 5.64808 +944 5.0414 +945 4.07399 +946 8.06578 +947 5.13059 +948 3.32765 +949 6.87378 +950 6.8715 +951 5.34151 +952 7.4087 +953 4.97386 +954 4.34552 +955 4.26796 +956 4.19602 +957 3.42375 +958 5.85754 +959 5.66926 +960 8.16791 +961 5.85989 +962 5.27303 +963 4.04843 +964 3.73455 +965 6.69521 +966 3.19527 +967 5.41381 +968 4.9373 +969 3.34371 +970 5.277 +971 5.14515 +972 4.27359 +973 3.45159 +974 4.18209 +975 3.97173 +976 6.6748 +977 5.48345 +978 5.03449 +979 6.2847 +980 4.28563 +981 4.42304 +982 8.30151 +983 8.10918 +984 5.2181 +985 6.07928 +986 7.4987 +987 3.86094 +988 7.79415 +989 4.1437 +990 4.22013 +991 4.84238 +992 4.18954 +993 4.63546 +994 5.03533 +995 5.68754 +996 3.66053 +997 4.99215 +998 3.9023 +999 6.64228 +1000 3.66927 +1001 7.59005 +1002 7.84943 +1003 6.12621 +1004 4.28124 +1005 5.25678 +1006 4.49358 +1007 3.83982 +1008 4.1934 +1009 4.15133 +1010 5.9278 +1011 6.99563 +1012 5.9841 +1013 8.90109 +1014 7.652 +1015 7.06981 +1016 4.2989 +1017 4.43713 +1018 3.94864 +1019 5.25543 +1020 5.67571 +1021 4.55211 +1022 5.55705 +1023 4.35115 +1024 3.53053 +1025 4.95254 +1026 5.0626 +1027 5.91199 +1028 3.64351 +1029 4.37971 +1030 6.08977 +1031 8.17508 +1032 9.08688 +1033 6.27308 +1034 5.95361 +1035 5.76509 +1036 4.96722 +1037 5.54433 +1038 4.46812 +1039 5.33303 +1040 6.1708 +1041 6.72636 +1042 5.29678 +1043 4.55251 +1044 8.94976 +1045 3.51383 +1046 9.65923 +1047 5.82992 +1048 4.65022 +1049 4.9202 +1050 5.80657 +1051 3.98189 +1052 5.41173 +1053 4.62405 +1054 3.74779 +1055 3.72462 +1056 4.19243 +1057 8.98073 +1058 5.19122 +1059 4.03261 +1060 3.37577 +1061 5.38447 +1062 7.73223 +1063 8.13835 +1064 4.25916 +1065 4.74505 +1066 7.41008 +1067 7.34217 +1068 4.67887 +1069 7.30568 +1070 4.68001 +1071 4.1343 +1072 4.30236 +1073 4.91304 +1074 3.81816 +1075 4.33604 +1076 7.30661 +1077 3.71466 +1078 5.48295 +1079 5.02695 +1080 5.64749 +1081 4.97985 +1082 5.0635 +1083 4.18982 +1084 6.63653 +1085 6.50817 +1086 4.06997 +1087 4.6217 +1088 3.9456 +1089 5.86381 +1090 4.34958 +1091 4.72955 +1092 7.68562 +1093 4.76352 +1094 4.38867 +1095 7.24025 +1096 8.56583 +1097 7.12327 +1098 7.63126 +1099 4.98995 +1100 5.51299 +1101 6.22274 +1102 8.55485 +1103 4.67541 +1104 5.56093 +1105 4.11592 +1106 5.39012 +1107 4.91738 +1108 4.55802 +1109 9.81191 +1110 9.03824 +1111 4.91096 +1112 5.68686 +1113 5.43295 +1114 4.5376 +1115 7.76145 +1116 6.56722 +1117 5.56414 +1118 6.48512 +1119 7.08636 +1120 4.86379 +1121 5.06374 +1122 4.43781 +1123 6.37562 +1124 8.00607 +1125 5.72785 +1126 7.44421 +1127 8.55665 +1128 5.86133 +1129 9.30702 +1130 5.39706 +1131 9.72751 +1132 3.48947 +1133 4.01753 +1134 6.24749 +1135 5.18517 +1136 3.7291 +1137 5.12041 +1138 5.72019 +1139 8.40329 +1140 4.29092 +1141 6.32703 +1142 4.81643 +1143 6.2805 +1144 8.28778 +1145 6.11067 +1146 4.67958 +1147 6.84822 +1148 6.91117 +1149 8.73063 +1150 5.19026 +1151 8.76106 +1152 7.46817 +1153 4.01789 +1154 4.79286 +1155 4.32607 +1156 8.23324 +1157 4.8066 +1158 6.2838 +1159 6.4227 +1160 9.33195 +1161 4.68307 +1162 6.92146 +1163 6.30771 +1164 7.57291 +1165 7.22122 +1166 6.39772 +1167 5.60827 +1168 3.81708 +1169 3.25156 +1170 8.08526 +1171 7.77888 +1172 4.56788 +1173 8.09687 +1174 3.49101 +1175 4.88315 +1176 9.9666 +1177 5.09136 +1178 4.89489 +1179 8.84418 +1180 4.97986 +1181 5.33513 +1182 5.84621 +1183 3.85303 +1184 4.81127 +1185 7.16765 +1186 5.06141 +1187 7.20188 +1188 4.7328 +1189 5.06946 +1190 3.66104 +1191 4.29874 +1192 3.89884 +1193 6.80851 +1194 5.53224 +1195 7.4339 +1196 5.48488 +1197 8.32916 +1198 5.44496 +1199 5.953 +1200 7.10064 +1201 4.28803 +1202 5.27418 +1203 3.79067 +1204 3.44724 +1205 4.17183 +1206 7.19842 +1207 4.32375 +1208 3.51299 +1209 7.615 +1210 5.69386 +1211 6.73423 +1212 4.51568 +1213 6.08616 +1214 5.21758 +1215 8.14411 +1216 4.06477 +1217 5.22976 +1218 5.07475 +1219 5.92439 +1220 4.9689 +1221 5.09276 +1222 7.43835 +1223 6.71407 +1224 7.02283 +1225 6.5295 +1226 4.40292 +1227 5.83422 +1228 3.70634 +1229 3.52758 +1230 6.0864 +1231 4.79487 +1232 5.2648 +1233 6.60461 +1234 4.95882 +1235 9.41937 +1236 5.13095 +1237 5.28013 +1238 5.44854 +1239 7.71878 +1240 5.56885 +1241 8.76006 +1242 4.56393 +1243 5.90289 +1244 6.17245 +1245 5.47762 +1246 6.85481 +1247 3.17205 +1248 4.86204 +1249 4.43452 +1250 6.97671 +1251 5.3337 +1252 5.43708 +1253 5.01141 +1254 7.23168 +1255 3.70348 +1256 4.66871 +1257 8.66635 +1258 7.63642 +1259 6.58896 +1260 5.63525 +1261 5.18847 +1262 4.60493 +1263 8.295 +1264 7.64526 +1265 3.59029 +1266 8.30829 +1267 5.61988 +1268 4.40627 +1269 8.59727 +1270 7.237 +1271 5.90024 +1272 4.03286 +1273 4.8429 +1274 7.10562 +1275 6.50655 +1276 4.64487 +1277 4.69878 +1278 7.97432 +1279 4.02501 +1280 5.38605 +1281 4.92341 +1282 5.07646 +1283 3.75685 +1284 5.31243 +1285 5.7707 +1286 5.68964 +1287 5.96062 +1288 7.85077 +1289 8.21576 +1290 6.68323 +1291 4.30884 +1292 4.784 +1293 5.21908 +1294 4.82005 +1295 4.40245 +1296 4.02024 +1297 3.62885 +1298 3.78701 +1299 3.55008 +1300 4.66264 +1301 5.58137 +1302 4.33701 +1303 4.93396 +1304 3.52374 +1305 7.13144 +1306 5.36387 +1307 8.97625 +1308 5.18498 +1309 9.05048 +1310 8.19838 +1311 4.42885 +1312 8.34232 +1313 3.94079 +1314 4.41342 +1315 7.69708 +1316 4.03687 +1317 4.88914 +1318 4.97387 +1319 5.60074 +1320 3.64249 +1321 3.99359 +1322 5.05358 +1323 7.22987 +1324 9.02307 +1325 3.92924 +1326 5.90228 +1327 6.68582 +1328 9.38571 +1329 4.23719 +1330 3.91918 +1331 6.00412 +1332 8.07751 +1333 4.80956 +1334 5.50254 +1335 9.28165 +1336 4.67539 +1337 4.8626 +1338 6.60907 +1339 6.82969 +1340 5.02785 +1341 4.99683 +1342 7.89183 +1343 9.24249 +1344 5.19206 +1345 4.25973 +1346 5.32035 +1347 4.13126 +1348 5.9532 +1349 6.48769 +1350 3.89076 +1351 5.66956 +1352 7.52047 +1353 5.81182 +1354 7.64656 +1355 5.39628 +1356 5.38481 +1357 4.57187 +1358 7.85941 +1359 3.19563 +1360 4.16723 +1361 7.58062 +1362 5.43379 +1363 4.5491 +1364 9.55822 +1365 5.41463 +1366 3.93709 +1367 5.58151 +1368 7.63004 +1369 7.19653 +1370 6.21067 +1371 4.16437 +1372 7.03794 +1373 6.03681 +1374 7.32543 +1375 8.75148 +1376 9.85852 +1377 5.51133 +1378 8.69481 +1379 5.56414 +1380 6.99819 +1381 3.55529 +1382 5.3928 +1383 4.84586 +1384 7.9864 +1385 6.53059 +1386 4.99042 +1387 4.16435 +1388 6.80177 +1389 5.45811 +1390 5.63078 +1391 3.96717 +1392 3.86136 +1393 3.20475 +1394 8.36851 +1395 5.32051 +1396 4.09927 +1397 4.30378 +1398 6.53894 +1399 9.57378 +1400 6.55006 +1401 6.34936 +1402 4.66909 +1403 4.92672 +1404 6.29711 +1405 6.13071 +1406 7.07983 +1407 3.38745 +1408 6.19644 +1409 3.70599 +1410 8.72514 +1411 5.01474 +1412 6.35499 +1413 8.51238 +1414 6.1006 +1415 8.31744 +1416 8.69373 +1417 5.3837 +1418 3.29415 +1419 3.17415 +1420 4.65337 +1421 3.77393 +1422 3.8875 +1423 7.11242 +1424 4.79596 +1425 4.074 +1426 4.91429 +1427 5.40041 +1428 4.50152 +1429 6.82147 +1430 7.03258 +1431 9.84567 +1432 5.28303 +1433 3.28496 +1434 5.3585 +1435 5.80604 +1436 6.24381 +1437 3.80452 +1438 8.7948 +1439 6.69635 +1440 5.38362 +1441 8.19043 +1442 6.65785 +1443 5.14952 +1444 8.66002 +1445 6.98012 +1446 5.82976 +1447 4.7057 +1448 4.19243 +1449 4.46766 +1450 4.94058 +1451 8.7967 +1452 5.51495 +1453 4.0043 +1454 5.16481 +1455 6.42095 +1456 6.01744 +1457 3.71544 +1458 5.73042 +1459 8.12425 +1460 3.95837 +1461 7.51813 +1462 9.24805 +1463 7.61923 +1464 4.43411 +1465 3.83737 +1466 3.95716 +1467 7.15998 +1468 5.65757 +1469 3.42947 +1470 7.66079 +1471 5.68317 +1472 4.17696 +1473 3.43991 +1474 4.08425 +1475 6.28225 +1476 5.03584 +1477 5.6927 +1478 4.82533 +1479 7.60644 +1480 3.80633 +1481 7.85466 +1482 4.0313 +1483 5.53088 +1484 4.79008 +1485 6.91984 +1486 7.05097 +1487 5.06758 +1488 5.28323 +1489 3.97634 +1490 7.07548 +1491 6.99741 +1492 5.39725 +1493 3.70965 +1494 5.20786 +1495 3.35697 +1496 8.30445 +1497 6.24412 +1498 5.02406 +1499 4.3192 +1500 3.75267 +1501 3.75419 +1502 6.70461 +1503 7.29339 +1504 7.25608 +1505 4.67025 +1506 7.00533 +1507 4.95845 +1508 5.9428 +1509 8.22798 +1510 6.09413 +1511 6.69181 +1512 4.68312 +1513 8.54909 +1514 9.17576 +1515 4.67904 +1516 5.70206 +1517 3.82361 +1518 4.83649 +1519 4.49647 +1520 6.62776 +1521 3.87563 +1522 3.82749 +1523 7.136 +1524 5.46372 +1525 7.49927 +1526 4.77056 +1527 6.99557 +1528 5.41681 +1529 5.67049 +1530 9.09783 +1531 6.2033 +1532 5.7676 +1533 6.10859 +1534 5.64874 +1535 4.25459 +1536 4.24224 +1537 7.54998 +1538 4.6898 +1539 3.65217 +1540 6.77849 +1541 7.38216 +1542 5.01269 +1543 9.63731 +1544 5.93312 +1545 6.67582 +1546 4.31103 +1547 7.11233 +1548 9.36116 +1549 5.26081 +1550 5.69302 +1551 3.48767 +1552 6.63839 +1553 6.58539 +1554 7.28664 +1555 3.81367 +1556 4.57632 +1557 5.76642 +1558 5.47675 +1559 4.10006 +1560 7.47012 +1561 4.71169 +1562 7.33109 +1563 3.61097 +1564 7.2049 +1565 5.17177 +1566 5.69784 +1567 5.66136 +1568 5.26364 +1569 5.80611 +1570 6.17947 +1571 7.04854 +1572 8.77365 +1573 4.85623 +1574 3.77604 +1575 4.3199 +1576 5.59875 +1577 7.20581 +1578 8.22279 +1579 6.75557 +1580 6.15071 +1581 8.40391 +1582 5.84813 +1583 6.71808 +1584 9.4805 +1585 5.78575 +1586 5.53995 +1587 6.22247 +1588 6.41044 +1589 4.20686 +1590 5.13741 +1591 9.43675 +1592 4.7142 +1593 3.98455 +1594 7.70331 +1595 5.7983 +1596 5.38736 +1597 6.27297 +1598 5.693 +1599 7.78512 +1600 9.5604 +1601 3.88507 +1602 5.01882 +1603 7.63484 +1604 5.06804 +1605 4.18197 +1606 4.43359 +1607 4.34535 +1608 4.02395 +1609 7.2371 +1610 8.47037 +1611 4.49746 +1612 8.23039 +1613 4.43065 +1614 4.82179 +1615 7.15842 +1616 4.60424 +1617 4.60142 +1618 4.98153 +1619 4.82699 +1620 6.48302 +1621 5.81494 +1622 9.77863 +1623 9.18164 +1624 8.97711 +1625 6.39388 +1626 4.3432 +1627 8.33951 +1628 5.09327 +1629 5.99447 +1630 4.3455 +1631 6.29698 +1632 3.33295 +1633 6.59657 +1634 6.95084 +1635 3.19532 +1636 5.517 +1637 5.79544 +1638 5.11606 +1639 5.09728 +1640 6.96594 +1641 4.43697 +1642 8.62959 +1643 6.33994 +1644 4.6679 +1645 6.9788 +1646 4.62802 +1647 9.58879 +1648 4.3363 +1649 5.16264 +1650 7.16104 +1651 5.92186 +1652 7.45343 +1653 3.24729 +1654 9.37208 +$EndElementData diff --git a/test/user/testdata/shark_22_binary_fTetWild.msh b/test/user/testdata/shark_22_binary_fTetWild.msh new file mode 100644 index 0000000000000000000000000000000000000000..9176430fe85d1dd93c2b64dbf1798c841ef694f9 GIT binary patch literal 70508 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 z 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 + diff --git a/test/user/testdata/shark_22_binary_gmshApp.msh b/test/user/testdata/shark_22_binary_gmshApp.msh new file mode 100644 index 0000000000000000000000000000000000000000..6438f183d90fd832b42dd814f9dcbcd94e81f9a8 GIT binary patch literal 83523 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 C#+c~< literal 0 HcmV?d00001 diff --git a/test/user/testdata/shark_22_binary_gmshApp.xml b/test/user/testdata/shark_22_binary_gmshApp.xml new file mode 100644 index 00000000..30d2bf3a --- /dev/null +++ b/test/user/testdata/shark_22_binary_gmshApp.xml @@ -0,0 +1,25 @@ + + diff --git a/test/user/testdata/shark_41_ascii_gmshApp.msh b/test/user/testdata/shark_41_ascii_gmshApp.msh new file mode 100644 index 00000000..ab7e2de6 --- /dev/null +++ b/test/user/testdata/shark_41_ascii_gmshApp.msh @@ -0,0 +1,2973 @@ +$MeshFormat +4.1 0 8 +$EndMeshFormat +$Entities +0 0 0 1 +0 -0.07334360000000001 -0.08523339999999999 -0.0005566629999999989 0.07028570000000001 0.0819076 0.0752128 0 0 +$EndEntities +$Nodes +1 652 1 652 +3 0 0 652 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +-0.07334359999999999 0.08167480000000001 0.056402 +-0.07291259999999999 0.0537921 0.00170478 +-0.072634 0.0799069 0.0578949 +-0.0715817 0.0520377 0.00292576 +-0.0701949 0.08025690000000001 0.0450431 +-0.06876980000000001 0.060971 0.00326551 +-0.06778000000000001 0.060358 0.00473741 +-0.06727959999999999 0.08092489999999999 0.0425553 +-0.0658074 0.0806443 0.0552302 +-0.064933 0.0788176 0.0453762 +-0.0636555 0.0610198 0.00141989 +-0.0636111 0.0566004 -0.000556663 +-0.0636791 0.0819076 0.0524468 +-0.0623445 0.0580268 0.00335683 +-0.0624856 0.06710579999999999 0.00581638 +-0.0601398 0.0781111 0.0317589 +-0.0599443 0.0685632 0.009924489999999999 +-0.0592787 0.0571239 0.00105116 +-0.0587906 0.07199990000000001 0.0117948 +-0.0575605 0.0730663 0.016213 +-0.057624 0.0811803 0.0403639 +-0.0572339 0.0769387 0.0223219 +-0.0559974 0.0749629 0.0235691 +-0.0542321 0.0763209 0.0344665 +-0.0540672 0.0649483 0.008218130000000001 +-0.0541685 0.06611350000000001 0.00437935 +-0.0532966 0.0805356 0.0466758 +-0.0517252 0.07611850000000001 0.0183218 +-0.0505257 0.06887699999999999 0.0152572 +-0.0503803 0.07726379999999999 0.0406423 +-0.0472855 0.0641041 0.00381053 +-0.0469016 0.0648796 0.00821733 +-0.0474599 0.07272679999999999 0.0265623 +-0.0464733 0.070912 0.0103373 +-0.0444756 0.07556740000000001 0.0221683 +-0.0440208 0.07743129999999999 0.0371107 +-0.0434135 0.0685101 0.0213943 +-0.0425401 0.0668787 0.0159114 +-0.0405353 0.07301630000000001 0.0309862 +-0.0386417 0.073548 0.0160682 +-0.037401 0.0664899 0.0122191 +-0.0358693 0.06894450000000001 0.0243885 +-0.0351058 0.06877709999999999 0.0124837 +-0.0333614 0.07116500000000001 0.0238503 +-0.0325564 0.0696271 0.024504 +-0.032455 0.0625178 0.0200737 +-0.0305469 0.0729973 0.0173921 +-0.0276941 0.06523859999999999 0.0128238 +-0.0272717 0.0628782 0.0141328 +-0.0263428 0.00735496 0.00505748 +-0.0256055 0.00658056 0.00327552 +-0.0252856 0.0610141 0.0227762 +-0.0250237 -0.00678856 0.00359213 +-0.0242889 -0.00589458 0.00589675 +-0.0216872 0.0639735 0.0255561 +-0.0215721 -0.0119744 0.00619585 +-0.0195136 0.0542304 0.0216195 +-0.0168343 0.06495339999999999 0.0236547 +-0.0161373 -0.00420129 0.00881529 +-0.0148726 0.0585475 0.0106707 +-0.0140647 0.0517836 0.0159197 +-0.0142986 0.0543801 0.0051496 +-0.0139611 -0.0178642 0.00651265 +-0.0139803 0.0554055 0.0115694 +-0.0124373 0.0606817 0.0122622 +-0.0127423 0.0580719 0.0285553 +-0.0127412 -0.07042320000000001 0.0234664 +-0.0126173 -0.0801905 0.022154 +-0.0125269 0.0592002 0.0346418 +-0.0122498 -0.080596 0.0191154 +-0.0121442 -0.0691943 0.0191352 +-0.0123618 0.0658492 0.0197519 +-0.0121018 -0.063334 0.0245151 +-0.0118539 0.0462485 0.0243954 +-0.0111067 0.0637388 0.0161162 +-0.0110042 -0.0624802 0.0276395 +-0.0109072 0.046219 0.0183571 +-0.0107037 -0.000325242 0.00950432 +-0.010183 -0.0121386 0.00674337 +-0.009774420000000001 -0.0638147 0.0162637 +-0.0097669 -0.06993340000000001 0.0156591 +-0.00942656 -0.0836042 0.0182705 +-0.009320999999999999 -0.0852334 0.0216727 +-0.00803502 0.0401179 0.0263407 +-0.00857808 -0.0579335 0.0163943 +-0.007931580000000001 -0.0190616 0.0121625 +-0.00782675 0.0573514 0.028038 +-0.00773028 -0.0620746 0.0302044 +-0.00764665 0.0537773 0.00961295 +-0.00721562 -0.0507362 0.0224357 +-0.00717408 -0.0528249 0.0179333 +-0.00651588 -0.00739691 0.013024 +-0.00691116 -0.00014073 0.00823716 +-0.00661131 0.044183 0.0123 +-0.00658663 0.0535365 0.0326225 +-0.00630954 -0.08506569999999999 0.0194796 +-0.00616497 -0.0797841 0.0261073 +-0.00582999 -0.0494502 0.0287705 +-0.00563359 0.0476479 0.00934546 +-0.00506609 -0.0425596 0.0250833 +-0.00453974 -0.0405694 0.0173853 +-0.00447266 0.0319291 0.0205877 +-0.00434886 0.0267225 0.00648417 +-0.00418386 0.0253438 0.008421959999999999 +-0.0041733 -0.0606038 0.0122716 +-0.00385183 0.0479538 0.00869149 +-0.00333705 0.051389 0.031593 +-0.00333565 -0.06938809999999999 0.0119551 +-0.00333748 -0.0650683 0.0110291 +-0.00292457 0.0475597 0.0319288 +-0.00280471 -0.0353375 0.0238411 +-0.00273019 -0.0493159 0.0135756 +-0.00255346 -0.0452657 0.0126112 +-0.00249178 -0.0598565 0.010934 +-0.00247351 -0.0533955 0.0149632 +-0.00280465 0.0288144 0.0300227 +-0.00225175 -0.030519 0.0236922 +-0.00205777 -0.0595101 0.00715068 +-0.0018581 -0.0627033 0.0116048 +-0.00150112 -0.0384203 0.0313885 +-0.00143547 -0.0337232 0.0176227 +-0.00136747 -0.062725 0.0150152 +-0.000884775 -0.0587825 0.0143119 +-0.000624659 -0.0247814 0.0257906 +-0.000489974 0.0225414 0.0188523 +-6.05566e-05 0.0171338 0.0234086 +0.00150381 0.0360475 0.00675461 +0.000282178 -0.0241462 0.0174969 +0.000347869 -0.06752370000000001 0.0324883 +0.000429839 -0.0422219 0.0349169 +0.00028168 -0.0273698 0.0312235 +0.000952705 -0.0267391 0.0143612 +0.00105244 0.0186951 0.00689988 +0.0011109 -0.0779453 0.014663 +0.00137887 0.00842564 0.0258445 +0.00107238 -0.0462225 0.00980545 +0.00158113 -0.0561697 0.005809 +0.00165921 -0.0142314 0.0114909 +0.00169065 -0.00330978 0.027848 +0.0017282 0.0264299 0.00972258 +0.00196109 -0.062067 0.0125082 +0.00198494 -0.0249792 0.0122768 +0.00206797 -0.0322322 0.0125632 +0.00219287 -0.00991015 0.0199027 +0.00223228 -0.065619 0.00972103 +0.00226787 -0.06664 0.0139131 +0.00233081 0.009707510000000001 0.0349608 +0.0023033 -0.0550711 0.0357611 +0.00284591 -0.06958739999999999 0.0109337 +0.00313658 0.0123831 0.0152878 +0.00325266 -0.000639164 0.0164744 +0.00354678 -0.0651674 0.00553443 +0.00434877 0.0392681 0.00656793 +0.0034004 -0.0624097 0.0143354 +0.00410027 0.052311 0.0146156 +0.00425687 -0.0110681 0.0377954 +0.0043501 -0.0020508 0.015115 +0.00444422 -0.0785667 0.0168482 +0.00471578 -0.008727459999999999 0.0133588 +0.00486541 0.0192794 0.0102326 +0.00475235 0.0259901 0.00777948 +0.00497525 -0.0797755 0.0244877 +0.0052286 0.0545416 0.0234287 +0.00513856 -0.0361953 0.00904286 +0.00543656 -0.016404 0.0117933 +0.00521097 0.0361763 0.0357574 +0.00563068 0.0458779 0.0101474 +0.00602624 -0.0598053 0.00448538 +0.00669265 -0.0730234 0.0300997 +0.00671975 -0.0647944 0.0149968 +0.00743572 0.0219428 0.00498754 +0.00806977 -0.06766220000000001 0.0106835 +0.008580020000000001 0.0185363 0.00804532 +0.00900922 -0.0527441 0.0382868 +0.00967438 -0.0310472 0.0412759 +0.009690270000000001 -0.0470756 0.00574739 +0.009825469999999999 -0.0777201 0.0238208 +0.010337 -0.0646559 0.00738197 +0.0103691 -0.0715108 0.0301524 +0.0108524 -0.06519229999999999 0.0107074 +0.0112352 0.0223598 0.00496048 +0.0115762 0.0360388 0.034027 +0.011811 0.0150563 0.0411225 +0.0119389 -0.07108730000000001 0.0142927 +0.011481 0.000850754 0.00890493 +0.0122581 0.0177891 0.00726338 +0.0126044 0.0285097 0.0071727 +0.0126077 -0.0410848 0.00487059 +0.01325 0.0245576 0.00385279 +0.0133342 -0.0301914 0.00695184 +0.0134526 -0.00467313 0.044297 +0.0140263 0.0415073 0.0128325 +0.0139319 -0.0627506 0.0126489 +0.0144402 0.0213321 0.0408733 +0.0145153 -0.0120242 0.00709154 +0.0145254 0.0314471 0.00762861 +0.0143606 -0.0539791 0.00638859 +0.0153705 -0.0588177 0.00913193 +0.0158483 0.0424843 0.0267153 +0.0161677 0.0082135 0.0752128 +0.0160709 -0.0693691 0.0267104 +0.0163112 0.021127 0.00658374 +0.0163956 0.0418119 0.0180916 +0.0166653 0.00513625 0.0449469 +0.0171438 -0.009394380000000001 0.0462661 +0.0174416 -0.0497054 0.0373642 +0.0174198 -0.06569369999999999 0.0159871 +0.0177387 0.0346114 0.0053358 +0.0178439 0.0247259 0.00729322 +0.018247 0.0346901 0.00258831 +0.0182074 -0.0318958 0.0424624 +0.0183988 -0.00142899 0.0496692 +0.0188182 -0.018825 0.0447569 +0.0188285 0.0147456 0.0461032 +0.0188626 0.015416 0.041072 +0.0190811 -0.00419709 0.06868580000000001 +0.0195945 0.0084326 0.064095 +0.0197498 -0.00217441 0.0583864 +0.0198208 0.00539755 0.0587622 +0.0200137 0.0324539 0.00354185 +0.020151 -0.0145671 0.0500049 +0.0203386 -0.00326709 0.07024469999999999 +0.0209148 0.00523036 0.0681576 +0.0208447 0.0121045 0.0546374 +0.0209724 0.009706330000000001 0.0633876 +0.020604 -0.0121123 0.00591309 +0.0212498 -0.0289526 0.00565549 +0.0216078 -0.0380775 0.00479088 +0.0216875 -0.00997672 0.0619769 +0.0220658 0.00705093 0.0456869 +0.0223002 -0.0558455 0.0110476 +0.0223137 -0.0154618 0.0494217 +0.0229336 0.00417573 0.0589573 +0.0231427 0.0278288 0.0125965 +0.0231751 0.027241 0.0309726 +0.0233259 0.0160686 0.00756079 +0.0234095 0.0318943 0.0199392 +0.0234462 -0.00393483 0.0583985 +0.0235915 -0.0597066 0.0170609 +0.0240196 -0.0108777 0.0466362 +0.024123 -0.00330273 0.0464733 +0.0242099 -0.0321428 0.0398591 +0.0244244 0.00347947 0.0416421 +0.024564 -0.0175604 0.0433407 +0.0253979 -0.0453083 0.0344803 +0.0256103 0.0267734 0.0284514 +0.0259312 -0.0445208 0.00878379 +0.025959 -0.0133125 0.00624018 +0.0265967 -0.0369666 0.00635268 +0.0273245 -0.0066598 0.0412078 +0.0277597 -0.0467651 0.0304517 +0.0275944 -0.0515878 0.0207552 +0.0282687 0.0208205 0.0174814 +0.0290859 0.0112094 0.012597 +0.0293048 -0.0474855 0.0256026 +0.0296506 -0.0466043 0.0156453 +0.0304236 0.0134394 0.031696 +0.0304518 -0.0291908 0.00746031 +0.03126 -0.044124 0.016095 +0.0321715 -0.043346 0.0242104 +0.0322352 -0.0402733 0.0141242 +0.0323149 0.01052 0.0200521 +0.0324768 -0.0397188 0.0271188 +0.0325431 -0.0291932 0.0340382 +0.0332479 -0.0329826 0.0117351 +0.0338676 -0.0346121 0.0252676 +0.0341522 -0.00293196 0.033596 +0.0341882 -0.0361716 0.0179088 +0.0344969 -0.0256263 0.0309923 +0.0345138 -0.00958586 0.0123416 +0.0348872 -0.0128566 0.0339912 +0.0349524 -0.0273994 0.0177976 +0.0349556 -0.000677158 0.0209767 +0.0350004 -0.028049 0.008761420000000001 +0.0353194 -0.0100316 0.0154749 +0.0354214 -0.0195455 0.0173172 +0.0355775 -0.0309821 0.0107592 +0.0360305 -0.0150581 0.0232372 +0.0363938 -0.0285041 0.0132933 +0.0374738 -0.00607371 0.0123945 +0.041317 -0.0210454 0.0131228 +0.0425886 -0.0120136 0.0129537 +0.0475164 -0.00753527 0.00853843 +0.0492593 -0.00704914 0.009380670000000001 +0.0496752 -0.0170405 0.0106038 +0.0498676 -0.0259318 0.00619626 +0.052402 -0.022331 0.00866719 +0.0516897 -0.011391 0.0103437 +0.0559595 -0.0106346 0.00698866 +0.0596531 -0.0214295 0.0059579 +0.066312 -0.0158462 0.00759335 +0.0672852 -0.00331292 0.00667068 +0.0687074 -0.0027598 0.00829441 +0.0687083 -0.008451500000000001 0.00881385 +0.07028570000000001 -0.00694567 0.00665748 +0.02471 0.00101921 0.00688758 +0.00641783 -0.0341512 0.0233596 +0.024018 0.00854392 0.00722419 +0.0251696 0.009421270000000001 0.00784613 +-0.019815 0.0686939 0.0189821 +0.0416697 -0.017118 0.00864259 +-0.00440288 -0.06984319999999999 0.0205811 +-0.0033606 0.0600219 0.0217676 +0.0268544 0.00322876 0.008082499999999999 +0.00855449 0.0107052 0.00928038 +0.0219179 0.00585482 0.0121236 +0.0199208 0.0175811 0.0336776 +0.0210521 -0.0362113 0.0256186 +0.0339797 -0.00194129 0.0163861 +0.03202 0.000337126 0.0126992 +0.0119633 0.0163586 0.0147908 +0.0248778 0.0056119 0.0321775 +0.00892971 -0.0563678 0.0287948 +0.0174837 0.027107 0.0210333 +-0.0170518 0.00346089 0.00554363 +0.0144974 -0.0120686 0.0314959 +0.00336155 -0.00103205 0.0364574 +0.00707711 -0.0204903 0.0185209 +0.010517 -0.00309481 0.0232445 +-0.00559352 0.0373259 0.0172753 +-0.00523735 -0.0230725 0.0111224 +0.0151072 -0.0538804 0.0213778 +0.0347571 -0.0188174 0.0105515 +0.0278657 -0.0183642 0.0156758 +-0.00338013 -0.0543805 0.0329679 +-0.0196332 0.0593213 0.0251138 +0.06481629999999999 -0.0143432 0.00627944 +-0.00336175 -0.0187472 0.00979996 +-0.0059938 -0.0214388 0.00941436 +0.0204933 0.0262773 0.00994486 +0.0153554 0.00838654 0.0105168 +-0.064082 0.064994 0.00682263 +-0.0406296 0.0703091 0.0249838 +-0.0197677 0.0563929 0.0156108 +-0.0506931 0.0781816 0.0304629 +0.0171972 -0.00100568 0.011485 +0.0314619 -0.0225976 0.00774901 +-0.00980694 0.0515267 0.0104574 +-0.00435185 0.0493969 0.0137744 +0.0449063 -0.0117353 0.00859937 +0.00159087 -0.0450385 0.027858 +-0.00469537 -0.06372510000000001 0.0233918 +0.0424219 -0.0285632 0.00857374 +0.0603894 -0.00835109 0.009350529999999999 +-0.0147113 -0.0156046 0.009183759999999999 +-0.0528157 0.0611754 0.00480955 +-0.0173765 -0.008871489999999999 0.00520522 +0.0108104 0.02268 0.0130558 +-0.00899905 -0.0208443 0.00915416 +-0.0449914 0.0768094 0.0302276 +-0.0408502 0.06658 0.008368489999999999 +-0.0199988 -0.0118916 0.004906 +0.00337131 0.0455887 0.0238561 +0.00477413 -0.0721541 0.0211645 +-0.00344193 -0.049333 0.032475 +0.0427245 -0.0268877 0.00738607 +0.0272704 -0.0238375 0.00669928 +-0.00610544 -0.0476638 0.0181008 +-0.00760153 0.0503529 0.00747858 +0.0131109 -0.0422224 0.0405109 +0.00214561 -0.0490294 0.0151357 +-0.0598224 0.0805424 0.0511855 +-0.0204542 0.0588165 0.013102 +0.059357 -0.0190886 0.00813027 +-0.00100716 0.0422264 0.0325724 +0.0325535 -0.0244764 0.012522 +-0.000431427 -0.0574818 0.0137747 +0.0114251 0.0275734 0.00440942 +0.00337666 -0.0559724 0.0148659 +-0.0262911 0.0586227 0.0207785 +-0.0699467 0.0813567 0.0499003 +0.0494602 -0.0133111 0.00757754 +0.00758285 0.0333008 0.0104911 +0.00657287 0.032122 0.00603963 +0.000332803 -0.0511328 0.0180756 +-0.021764 0.0620607 0.0118108 +-0.0454672 0.075167 0.035911 +0.00139884 0.045926 0.0128133 +0.0176314 0.0311493 0.00370344 +-0.0159418 -0.0158578 0.00793814 +-0.0229387 0.06916410000000001 0.0166572 +-0.00133409 -0.0449329 0.0187829 +-0.0538019 0.0611146 0.00198764 +0.0305208 -0.00256491 0.0101919 +0.0623596 -0.00697151 0.00683979 +0.0236819 -0.00777996 0.0526871 +0.0118138 -0.0144241 0.0430193 +0.0137156 -0.00365078 0.00732253 +-0.0257884 0.0686739 0.0150694 +-0.0530331 0.060812 0.00248197 +-0.000421194 -0.0523335 0.008791770000000001 +0.0193846 -0.00072024 0.0649221 +0.00485856 0.0133946 0.0114741 +-0.0053823 -0.0743714 0.0141262 +0.016958 0.0166471 0.00740593 +0.0429338 -0.0266961 0.0110582 +-0.06504749999999999 0.05473 0.00191127 +0.00924818 0.0356698 0.00715588 +-0.042468 0.0652669 0.00790867 +0.00699205 0.0348997 0.00576165 +-0.012123 0.00171435 0.00688121 +0.017741 0.00126373 0.0717161 +-0.00477874 -0.0228765 0.0123522 +-0.05496 0.0793832 0.0329037 +-0.0253736 -0.000654191 0.00342534 +0.0220159 -0.0128389 0.0555838 +0.0187915 0.00366305 0.06539010000000001 +-0.0635923 0.0794618 0.0351284 +0.0187293 0.00901455 0.0689246 +-0.0507436 0.0790633 0.0364811 +0.00440962 0.0291856 0.00589534 +-0.0610541 0.08157639999999999 0.0467801 +-0.0264169 0.06418980000000001 0.0180225 +0.0590681 -0.0129818 0.009692930000000001 +0.0316732 -0.013669 0.008927310000000001 +-0.0368828 0.0732351 0.028231 +0.0147007 -0.0293577 0.0425282 +-0.00226105 0.042112 0.008184220000000001 +-0.022404 0.068624 0.0211714 +0.018834 0.0296379 0.0101126 +0.0545664 -0.023882 0.00596013 +-0.0610274 0.0626039 0.00623226 +0.0209345 -0.0123916 0.0558755 +-0.064258 0.0639612 0.00701622 +-0.0530259 0.07099660000000001 0.0104874 +-0.000350232 0.0328643 0.009503569999999999 +0.0179821 0.0260225 0.00525665 +-0.071629 0.0809096 0.0500374 +0.0431333 -0.00662611 0.0109755 +-0.0367738 0.072104 0.0272887 +-0.00147996 0.0424733 0.00778004 +-0.0489442 0.0792518 0.0424775 +0.0178184 0.008309230000000001 0.0698262 +-0.00256208 -0.0518644 0.0119693 +-0.0024457 0.0347988 0.0115191 +-0.0226391 0.067054 0.0236986 +-0.0250562 0.070839 0.0181046 +0.0157661 -0.010775 0.0444953 +-0.0587069 0.0610686 0.00549325 +-0.0561989 0.0607157 0.00436391 +0.0028322 0.0311045 0.0076099 +-0.061857 0.079748 0.0514834 +-0.0580072 0.07448539999999999 0.0170926 +0.017366 0.0281829 0.00449304 +0.0175246 0.0303053 0.00632184 +-0.0583716 0.0812348 0.0494755 +-0.06276379999999999 0.08110589999999999 0.0418948 +0.009583370000000001 0.0391723 0.00889538 +0.0164997 0.0327763 0.00400793 +-0.0100537 -0.019407 0.0104569 +0.0535082 -0.023589 0.00757618 +-0.0184567 0.0672393 0.0165986 +-0.0660887 0.06395149999999999 0.00557639 +-0.008500499999999999 0.0591911 0.0132991 +0.0527123 -0.00658592 0.00801901 +0.00664445 0.0147496 0.00979726 +-0.0323364 0.06468409999999999 0.013176 +-0.06849810000000001 0.0817682 0.0541475 +0.0424951 -0.00680449 0.0104665 +-0.01583 0.06382989999999999 0.0140017 +-0.0408586 0.07478079999999999 0.0276312 +-0.0213675 0.00505684 0.00440033 +-0.0609542 0.0784149 0.029815 +0.0458286 -0.0196104 0.0115924 +0.0619857 -0.0044448 0.00717137 +-0.0549453 0.0736446 0.0144159 +-0.0660739 0.0797747 0.0511232 +-0.0150243 -0.0138696 0.00597473 +-0.0208919 0.06642729999999999 0.014553 +-0.0583912 0.07667309999999999 0.0277458 +-0.00499489 -0.0492059 0.0154875 +-0.0177596 -0.0149926 0.00640227 +-0.0656257 0.0638276 0.00437301 +-0.00111824 -0.0505712 0.010634 +-0.0234714 0.0595273 0.0150887 +-0.0117477 -0.00786715 0.0107629 +-0.0329423 0.0662408 0.012525 +-0.0588644 0.0778049 0.0265316 +-0.038272 0.07101209999999999 0.0277124 +0.0147178 0.0228905 0.00513556 +-0.00242697 -0.0228032 0.0106496 +-0.00998317 -0.0196685 0.00798312 +0.00194711 0.0338412 0.00734265 +-0.0101071 0.0571173 0.0108272 +-0.000192036 0.0305177 0.010316 +-0.06622359999999999 0.0609953 0.00234663 +-0.0383437 0.071981 0.0290737 +0.0464353 -0.0271448 0.00729223 +-0.0113654 0.0558876 0.00985606 +-0.0600686 0.0581853 0.00037707 +0.0184892 0.00651809 0.072001 +-0.0272353 0.0661385 0.0125002 +0.0386787 -0.009397559999999999 0.0110365 +-0.00702298 -0.0554164 0.0301677 +-0.0387296 0.0725599 0.0291973 +-0.0195884 -0.009713039999999999 0.00731553 +0.0009803979999999999 0.0340005 0.008311529999999999 +-0.00251349 -0.0493306 0.0137872 +-0.0208118 0.00468072 0.00662791 +0.0145465 0.0247675 0.00685396 +0.0539643 -0.00601143 0.00911787 +0.0615879 -0.00432066 0.00875869 +-0.0649217 0.0800024 0.0383643 +0.00460493 0.008497380000000001 0.0127005 +-0.0606311 0.0803611 0.0379233 +-0.00316884 0.0400824 0.00969248 +-0.0308482 0.067467 0.0126012 +0.0120049 0.00511369 0.00824306 +0.0117314 0.0134932 0.00784586 +0.0067401 0.0222359 0.00786688 +0.000365941 0.0444987 0.0334101 +0.00589042 0.0427357 0.0325284 +0.0134556 0.013691 0.0071386 +0.0155774 0.00572549 0.00675779 +-0.0442054 0.0654197 0.00607699 +0.00863004 0.0184766 0.00878081 +-0.0111016 -0.0170398 0.0107756 +-0.0162643 0.06208 0.0123266 +-0.06706429999999999 0.0628756 0.0047451 +-0.0673064 0.07917689999999999 0.0489333 +-0.0566743 0.0588231 0.00264455 +-0.07138410000000001 0.080001 0.0523997 +-0.0690781 0.0794039 0.0521145 +-0.0589744 0.07029879999999999 0.0123753 +-0.0108026 0.05228 0.00636676 +-0.0113486 0.0541547 0.00728553 +-0.0299136 0.06862409999999999 0.0165753 +0.0505332 -0.0225927 0.00635398 +0.0180077 0.0031318 0.07043870000000001 +-0.0235313 0.0640143 0.012641 +-0.0235569 0.00584404 0.00381922 +0.0384718 -0.0113423 0.0144484 +0.0182407 0.00232532 0.0728388 +-0.0235752 0.00407866 0.00373027 +-0.011585 0.0522432 0.00647843 +0.0400312 -0.00904366 0.0126741 +-0.0178591 -0.000359808 0.00797485 +-0.067167 0.06255139999999999 0.00392853 +-0.0596438 0.0779391 0.0290601 +0.0013543 0.0302152 0.00901705 +0.0168301 0.00522322 0.0737244 +0.0174324 0.00448014 0.0738384 +-0.0618546 0.0649931 0.00590465 +0.0194429 0.0304209 0.00452872 +-0.0236633 0.0648084 0.0124456 +-0.00249493 -0.0562542 0.012985 +-0.0025263 -0.0246783 0.0125409 +-0.0396392 0.0718092 0.02876 +-0.0158083 -0.0164708 0.00645267 +0.016879 0.0245859 0.0055459 +-0.06884990000000001 0.0811361 0.0461884 +0.0290982 -0.00647478 0.008279069999999999 +-0.041817 0.0761358 0.0343691 +-0.0642688 0.0653922 0.00517065 +-0.0162175 0.00239503 0.00694561 +0.00467524 0.0360758 0.00643588 +-0.0222973 0.0035638 0.00646752 +-0.0708092 0.0801688 0.0482801 +-0.0549524 0.07870829999999999 0.0296023 +-0.06310540000000001 0.0672415 0.00811831 +-0.0155444 -0.0163359 0.0060847 +-0.0574097 0.07880470000000001 0.0473507 +-0.0558952 0.0591814 0.001764 +-0.0177409 0.0619627 0.0144786 +-0.00178349 -0.0487397 0.0125937 +-0.0111058 0.0522074 0.008299040000000001 +-0.0260139 0.00360897 0.00461987 +-0.0204566 0.00423454 0.00564674 +0.00612936 0.0370467 0.00680554 +0.010446 0.0313554 0.00705031 +-0.0569353 0.05965 0.00118235 +-0.0506685 0.0625792 0.00279292 +-0.0249761 0.00485573 0.00443819 +0.0172421 0.00725128 0.07382619999999999 +-0.0219613 0.06430039999999999 0.0138184 +-0.00260185 -0.0513557 0.0142694 +-0.0167422 0.00259292 0.00779623 +0.00214524 0.0341103 0.00650831 +-0.0236765 0.00572293 0.004305 +-0.0616879 0.0784644 0.0353636 +-0.0125522 0.0533024 0.00573952 +-0.00373263 -0.048886 0.014509 +-0.00253347 -0.0472982 0.0131992 +-0.0128746 -0.017623 0.00940414 +-5.43548e-05 0.0393803 0.00728201 +-0.0258702 0.00405717 0.00525282 +0.0183599 0.0265636 0.00640112 +0.0459896 -0.0257989 0.0100883 +-0.0295424 0.06805940000000001 0.0247957 +-0.0245383 0.0634107 0.0123732 +0.0066096 0.0377811 0.00691952 +-0.0450015 0.0646553 0.00575343 +-0.0622505 0.0661482 0.00839783 +-0.0256248 0.0608105 0.0161665 +0.017488 0.00853314 0.07209649999999999 +-0.0596734 0.07050969999999999 0.009924850000000001 +-0.06657979999999999 0.06286890000000001 0.00493615 +-0.0624322 0.0664941 0.0080812 +0.0436037 -0.00911409 0.009504510000000001 +-0.0258241 0.00183578 0.00455937 +-0.07027029999999999 0.07969130000000001 0.0546337 +-0.027947 0.06304949999999999 0.0231884 +-0.0601839 0.07046330000000001 0.0106076 +-0.019796 -0.0130118 0.0069497 +-0.0183149 0.06305479999999999 0.012418 +-0.0302535 0.0701272 0.02364 +-0.0574291 0.07908510000000001 0.0314511 +-0.0506885 0.0650762 0.00396145 +-0.021101 0.0616869 0.0137094 +-0.0331684 0.0670427 0.023997 +0.0134393 0.00644533 0.00718965 +-0.0111807 -0.0194906 0.00818236 +-0.0255718 0.00304117 0.00332801 +-0.0126697 -0.015488 0.00653208 +-0.0247074 0.00660999 0.00551935 +0.0173416 0.0031807 0.0727906 +0.0172416 0.0236783 0.00588169 +0.0190309 0.0293428 0.00437137 +0.016715 0.00646681 0.0747173 +-0.0362286 0.072292 0.023504 +-0.0193589 -0.00042516 0.00470745 +-0.0218861 0.06436310000000001 0.0125137 +-0.0102557 0.0512168 0.00711881 +0.0404202 -0.00631757 0.0116411 +0.0462272 -0.00679819 0.0101561 +-0.0259792 0.0656558 0.0150971 +0.0162732 0.0229634 0.00624384 +0.00353474 0.0364474 0.008433390000000001 +4.6368e-06 0.0388726 0.009730829999999999 +-0.0216501 0.0633078 0.012475 +-0.06535530000000001 0.0635995 0.0060088 +-0.0129397 0.0533345 0.00604151 +-0.00189413 -0.0244631 0.013557 +-0.0610974 0.0673557 0.00916116 +0.0169636 0.00823874 0.0726305 +-0.0262169 0.00566462 0.00486021 +-0.00105663 -0.050339 0.013034 +-0.0522352 0.0618469 0.00239028 +-0.06586110000000001 0.0623674 0.00600767 +-0.0308719 0.0671807 0.0240148 +-0.0271033 0.0631674 0.0232081 +0.000463176 0.0377435 0.00713404 +0.0197653 -0.0105149 0.0573133 +-0.0261272 0.00574879 0.00514751 +-0.0256133 0.00236555 0.00535812 +0.0395658 -0.00664927 0.0115095 +-0.0346515 0.0704144 0.0260764 +-0.0676857 0.0619198 0.00410476 +-0.0352382 0.07226829999999999 0.0261851 +-0.0489272 0.0632235 0.00329626 +-0.0514659 0.0617489 0.00295197 +-0.070483 0.0805389 0.0464472 +$EndNodes +$Elements +1 1654 1 1654 +3 0 4 1654 +1 26 15 543 25 +2 227 308 190 188 +3 203 353 199 163 +4 331 305 504 150 +5 142 328 128 138 +6 490 439 18 571 +7 364 289 287 414 +8 296 336 304 298 +9 564 419 300 381 +10 398 569 373 591 +11 486 473 639 422 +12 338 89 566 489 +13 332 554 543 424 +14 80 67 71 302 +15 149 146 109 108 +16 98 90 375 342 +17 341 308 325 313 +18 147 314 126 116 +19 124 318 156 131 +20 245 322 206 308 +21 348 311 516 186 +22 135 150 319 151 +23 147 314 307 311 +24 464 588 301 528 +25 461 33 35 333 +26 196 192 373 314 +27 108 81 302 122 +28 366 258 227 357 +29 511 107 512 353 +30 146 170 354 172 +31 297 175 156 130 +32 130 297 175 308 +33 318 159 319 195 +34 154 123 122 342 +35 261 308 259 260 +36 132 142 128 318 +37 241 250 240 205 +38 226 227 248 324 +39 575 609 475 49 +40 375 91 123 90 +41 260 308 255 251 +42 517 612 63 482 +43 120 117 131 297 +44 318 131 297 156 +45 147 319 311 307 +46 131 120 297 130 +47 120 297 111 117 +48 308 174 206 360 +49 148 313 325 175 +50 148 313 175 174 +51 302 80 122 81 +52 107 353 511 110 +53 322 231 198 197 +54 61 58 564 57 +55 240 386 212 221 +56 121 297 143 117 +57 121 297 117 111 +58 307 235 314 182 +59 307 314 166 182 +60 417 308 175 316 +61 308 175 360 417 +62 601 9 458 1 +63 459 429 536 599 +64 211 242 206 308 +65 528 588 301 356 +66 316 297 308 175 +67 197 188 308 228 +68 231 308 228 197 +69 231 197 322 308 +70 188 197 308 361 +71 322 361 308 197 +72 259 308 256 255 +73 298 306 304 299 +74 302 342 146 122 +75 251 322 245 308 +76 298 306 299 236 +77 342 302 169 129 +78 157 319 331 150 +79 190 195 324 227 +80 146 342 354 154 +81 190 297 308 324 +82 236 254 306 299 +83 354 179 201 322 +84 308 297 188 361 +85 361 188 164 297 +86 195 165 190 318 +87 307 215 257 235 +88 194 235 215 307 +89 174 129 148 313 +90 169 313 129 174 +91 322 255 251 201 +92 366 265 308 258 +93 227 308 258 366 +94 258 308 249 265 +95 227 308 228 258 +96 448 192 373 196 +97 228 308 249 258 +98 296 298 514 336 +99 125 150 348 126 +100 125 160 348 150 +101 244 264 242 316 +102 264 316 244 271 +103 224 233 225 219 +104 107 353 163 199 +105 217 223 219 225 +106 308 174 313 206 +107 206 313 179 174 +108 241 230 212 233 +109 241 233 212 218 +110 267 278 312 273 +111 267 312 262 273 +112 206 179 322 245 +113 242 245 206 308 +114 144 319 159 157 +115 265 308 266 272 +116 218 219 392 233 +117 264 324 316 271 +118 324 308 264 316 +119 297 318 117 131 +120 128 117 318 124 +121 354 207 201 177 +122 207 177 354 184 +123 155 163 353 203 +124 131 297 156 130 +125 395 330 236 202 +126 164 142 318 190 +127 253 314 234 311 +128 307 314 147 166 +129 331 234 253 254 +130 306 236 298 331 +131 156 297 316 175 +132 324 319 318 316 +133 297 324 316 308 +134 373 314 102 125 +135 167 155 378 192 +136 278 324 272 269 +137 278 276 272 324 +138 319 159 157 336 +139 267 257 312 243 +140 307 215 243 257 +141 156 297 318 316 +142 207 354 170 184 +143 124 144 139 156 +144 267 312 250 243 +145 144 151 139 319 +146 318 316 319 144 +147 316 139 319 144 +148 139 144 316 156 +149 316 191 312 319 +150 316 191 317 156 +151 313 308 175 174 +152 253 234 331 311 +153 331 395 234 236 +154 272 265 308 366 +155 103 140 133 510 +156 235 199 246 314 +157 246 237 314 199 +158 144 151 319 157 +159 92 157 151 144 +160 92 159 157 144 +161 395 234 236 330 +162 395 330 202 348 +163 348 330 202 209 +164 324 312 316 271 +165 266 308 324 272 +166 324 366 308 227 +167 242 264 245 308 +168 272 266 269 324 +169 135 151 319 139 +170 40 35 28 29 +171 88 148 129 342 +172 325 342 148 88 +173 314 116 147 166 +174 77 353 320 94 +175 331 262 319 306 +176 319 317 139 316 +177 450 329 482 328 +178 183 307 147 166 +179 188 361 176 197 +180 169 179 313 174 +181 314 196 348 373 +182 102 84 116 353 +183 102 77 84 353 +184 191 147 319 317 +185 307 262 257 312 +186 307 257 246 235 +187 307 257 262 246 +188 128 318 144 124 +189 246 314 237 253 +190 314 203 237 234 +191 142 128 318 138 +192 253 237 234 314 +193 306 319 331 336 +194 307 314 235 246 +195 316 250 312 191 +196 450 403 349 329 +197 121 297 101 143 +198 382 164 101 297 +199 369 198 322 193 +200 264 266 324 269 +201 322 354 170 207 +202 322 170 193 207 +203 353 84 116 110 +204 70 302 68 83 +205 331 311 234 395 +206 323 493 282 301 +207 269 278 324 271 +208 278 312 324 271 +209 207 170 180 184 +210 207 170 193 180 +211 325 130 175 308 +212 146 354 170 154 +213 354 302 342 146 +214 161 348 510 181 +215 182 314 199 235 +216 322 354 369 170 +217 231 207 322 198 +218 313 322 375 341 +219 375 361 341 322 +220 322 207 193 198 +221 297 143 164 101 +222 221 213 240 232 +223 190 188 308 297 +224 341 361 375 382 +225 341 308 313 322 +226 134 158 184 354 +227 247 308 261 249 +228 263 308 260 251 +229 318 319 159 144 +230 309 262 306 319 +231 250 204 243 312 +232 448 192 167 378 +233 37 333 620 35 +234 37 33 333 35 +235 297 318 316 324 +236 167 448 378 153 +237 212 218 233 219 +238 88 325 342 494 +239 246 307 314 253 +240 307 253 246 262 +241 126 311 150 348 +242 388 611 336 514 +243 348 234 420 314 +244 236 254 331 306 +245 348 314 311 234 +246 211 308 360 417 +247 373 102 320 125 +248 316 250 191 438 +249 250 205 191 438 +250 254 262 306 309 +251 254 309 306 310 +252 299 254 306 310 +253 331 262 306 254 +254 292 294 295 293 +255 194 307 215 204 +256 304 306 384 299 +257 267 312 257 262 +258 353 192 378 155 +259 319 159 336 195 +260 353 192 373 378 +261 336 185 388 195 +262 312 250 271 267 +263 271 250 312 316 +264 261 249 308 265 +265 268 308 265 261 +266 247 308 249 228 +267 227 195 324 226 +268 366 324 415 337 +269 337 366 324 357 +270 190 195 318 324 +271 156 318 124 144 +272 263 266 308 264 +273 251 263 308 264 +274 197 198 322 369 +275 154 354 369 342 +276 188 308 228 227 +277 79 328 138 92 +278 316 317 139 156 +279 360 175 308 174 +280 255 251 308 322 +281 255 256 252 308 +282 247 228 231 308 +283 247 308 231 256 +284 134 149 394 354 +285 83 162 96 302 +286 161 373 140 348 +287 88 67 302 68 +288 302 97 88 68 +289 512 166 314 182 +290 420 192 314 234 +291 348 330 420 234 +292 192 314 234 203 +293 91 123 105 115 +294 394 70 302 81 +295 309 273 262 319 +296 319 262 312 273 +297 67 302 68 70 +298 271 278 312 267 +299 66 57 326 58 +300 188 136 176 361 +301 157 331 185 504 +302 136 361 188 164 +303 244 250 271 316 +304 71 302 67 70 +305 244 213 232 240 +306 81 302 71 70 +307 354 149 108 146 +308 314 237 203 199 +309 506 378 435 629 +310 244 438 316 213 +311 97 302 169 162 +312 244 316 438 250 +313 313 129 342 169 +314 382 113 101 164 +315 506 435 378 94 +316 91 123 85 105 +317 308 264 245 251 +318 242 264 308 316 +319 450 349 482 329 +320 314 373 348 125 +321 92 138 159 144 +322 395 311 234 348 +323 278 273 324 312 +324 373 378 435 320 +325 147 311 319 135 +326 126 311 135 150 +327 126 135 311 147 +328 314 348 311 126 +329 83 302 82 70 +330 378 435 629 373 +331 195 159 165 318 +332 316 312 324 319 +333 156 175 316 387 +334 336 298 514 331 +335 88 342 129 302 +336 319 307 331 311 +337 253 314 311 307 +338 311 331 253 307 +339 297 341 308 130 +340 314 348 126 125 +341 147 314 311 126 +342 61 339 99 338 +343 250 204 312 191 +344 305 185 508 331 +345 211 242 308 316 +346 211 308 417 316 +347 213 316 211 417 +348 214 215 230 204 +349 244 316 242 211 +350 244 211 213 316 +351 465 501 344 502 +352 108 354 302 394 +353 313 129 148 342 +354 337 324 415 248 +355 337 258 366 357 +356 121 101 297 111 +357 382 101 111 297 +358 157 159 185 336 +359 226 336 195 324 +360 307 262 331 253 +361 307 262 319 331 +362 331 254 253 262 +363 248 336 552 296 +364 319 324 195 336 +365 248 296 226 336 +366 324 248 336 552 +367 147 183 191 307 +368 282 281 276 323 +369 281 323 282 301 +370 109 119 105 122 +371 297 143 117 318 +372 109 122 105 80 +373 308 366 324 272 +374 297 318 324 190 +375 297 190 164 318 +376 214 204 230 212 +377 224 212 214 230 +378 297 143 318 164 +379 264 308 324 266 +380 264 269 324 271 +381 132 117 143 318 +382 130 297 341 120 +383 341 130 120 98 +384 277 343 356 279 +385 325 308 175 313 +386 109 81 108 122 +387 109 122 108 146 +388 348 234 395 330 +389 341 111 120 297 +390 341 100 98 120 +391 341 111 100 120 +392 226 336 324 248 +393 318 319 324 195 +394 275 270 324 309 +395 309 336 324 319 +396 552 270 336 324 +397 273 309 275 324 +398 403 328 329 450 +399 382 111 341 297 +400 361 322 308 341 +401 361 341 308 297 +402 342 85 73 90 +403 342 73 85 80 +404 323 324 366 276 +405 361 297 164 382 +406 96 82 83 302 +407 45 647 44 42 +408 179 354 201 177 +409 53 621 54 347 +410 117 124 131 318 +411 156 144 316 318 +412 369 198 193 141 +413 342 302 88 67 +414 67 80 342 302 +415 73 80 342 67 +416 342 73 67 76 +417 372 528 289 285 +418 285 528 289 287 +419 355 98 325 494 +420 122 119 105 123 +421 394 82 134 302 +422 494 88 76 342 +423 109 81 122 80 +424 447 580 503 505 +425 114 118 141 145 +426 311 150 319 135 +427 108 122 302 146 +428 204 307 183 194 +429 191 204 307 183 +430 382 101 100 111 +431 382 111 100 341 +432 318 159 138 144 +433 588 281 301 356 +434 87 61 77 57 +435 318 159 165 138 +436 7 12 2 486 +437 316 191 319 317 +438 208 196 449 445 +439 322 369 354 313 +440 354 158 177 162 +441 354 169 162 179 +442 313 369 354 342 +443 179 162 354 177 +444 130 98 341 355 +445 325 130 341 355 +446 337 357 324 248 +447 324 357 227 248 +448 588 281 464 301 +449 375 341 382 98 +450 454 75 61 155 +451 353 77 84 74 +452 331 305 185 504 +453 311 331 319 150 +454 378 339 167 106 +455 318 190 142 165 +456 138 142 165 318 +457 18 12 397 14 +458 298 514 331 513 +459 118 137 141 168 +460 298 331 236 395 +461 395 298 331 513 +462 93 157 92 159 +463 354 158 184 177 +464 151 157 92 93 +465 78 93 151 92 +466 378 448 629 153 +467 102 314 126 125 +468 126 116 314 102 +469 61 72 303 75 +470 39 461 350 553 +471 350 39 33 461 +472 311 331 513 395 +473 311 331 305 509 +474 353 102 314 116 +475 204 215 243 307 +476 106 153 167 378 +477 97 162 83 302 +478 107 353 199 512 +479 297 188 164 190 +480 147 319 139 135 +481 77 353 87 74 +482 353 203 199 314 +483 512 314 353 199 +484 37 38 29 35 +485 485 140 373 125 +486 398 448 373 196 +487 196 570 373 398 +488 324 248 552 415 +489 415 270 552 324 +490 52 57 594 564 +491 285 289 414 287 +492 438 250 205 240 +493 524 425 25 17 +494 29 25 524 425 +495 87 77 61 353 +496 93 92 138 159 +497 93 92 79 138 +498 203 192 353 155 +499 192 353 314 203 +500 88 302 129 97 +501 169 342 354 302 +502 147 319 317 139 +503 435 426 629 373 +504 197 168 369 176 +505 369 176 361 197 +506 157 151 319 150 +507 307 319 312 191 +508 312 307 191 204 +509 628 373 441 374 +510 513 331 311 509 +511 49 594 413 46 +512 303 163 87 61 +513 146 342 154 122 +514 274 366 415 337 +515 274 258 366 337 +516 87 57 74 66 +517 304 306 336 384 +518 204 250 205 191 +519 110 74 66 87 +520 163 87 61 353 +521 204 205 250 241 +522 387 438 213 316 +523 150 160 348 311 +524 313 369 342 375 +525 313 322 369 375 +526 97 129 169 302 +527 504 305 393 150 +528 181 348 500 187 +529 610 527 42 44 +530 44 527 42 620 +531 311 305 456 509 +532 311 509 456 516 +533 365 512 166 116 +534 116 512 166 314 +535 509 305 508 331 +536 322 369 193 170 +537 535 526 581 632 +538 182 314 512 199 +539 497 441 373 540 +540 37 42 46 527 +541 500 209 187 348 +542 312 257 307 243 +543 323 366 281 276 +544 348 420 209 196 +545 366 279 276 272 +546 202 500 186 348 +547 386 406 221 232 +548 64 526 62 489 +549 336 159 185 195 +550 404 24 559 335 +551 404 24 607 559 +552 384 336 552 270 +553 244 240 438 213 +554 244 438 240 250 +555 430 461 620 333 +556 461 333 35 620 +557 61 564 64 334 +558 381 437 47 413 +559 279 277 265 258 +560 279 277 258 274 +561 186 500 181 348 +562 140 510 348 160 +563 377 410 36 350 +564 202 330 236 209 +565 380 345 614 468 +566 99 339 378 106 +567 378 106 418 99 +568 378 448 373 629 +569 194 235 307 182 +570 194 307 166 182 +571 194 307 183 166 +572 353 373 320 378 +573 68 97 83 302 +574 347 496 604 476 +575 161 181 411 373 +576 570 374 400 368 +577 40 38 35 29 +578 364 289 327 528 +579 324 309 319 273 +580 353 378 320 94 +581 358 91 471 375 +582 134 394 302 354 +583 394 149 108 354 +584 172 354 146 149 +585 382 358 471 375 +586 101 382 90 358 +587 651 346 638 390 +588 382 90 100 101 +589 334 594 564 475 +590 369 361 375 322 +591 322 197 369 361 +592 342 325 98 494 +593 325 313 148 342 +594 342 325 375 98 +595 115 369 123 367 +596 342 98 76 494 +597 369 375 576 115 +598 353 512 116 314 +599 336 304 552 296 +600 336 306 304 298 +601 226 514 336 296 +602 108 302 81 394 +603 181 411 373 374 +604 26 440 571 383 +605 26 383 346 440 +606 211 360 308 206 +607 87 74 57 77 +608 358 113 101 382 +609 195 388 336 226 +610 241 233 218 238 +611 155 339 378 353 +612 345 79 468 476 +613 213 316 417 175 +614 387 316 213 175 +615 312 307 262 319 +616 435 485 426 373 +617 435 373 125 485 +618 299 310 306 384 +619 26 425 25 34 +620 118 114 367 434 +621 26 34 25 608 +622 223 222 529 392 +623 527 38 37 35 +624 37 527 46 38 +625 342 123 90 375 +626 342 123 85 90 +627 335 350 33 35 +628 350 461 33 35 +629 85 91 90 123 +630 259 247 308 261 +631 629 628 448 373 +632 633 142 328 128 +633 629 497 628 373 +634 303 61 87 72 +635 236 254 234 331 +636 341 98 325 355 +637 373 570 400 569 +638 398 570 373 569 +639 49 413 527 46 +640 49 46 527 457 +641 49 626 48 527 +642 241 204 243 250 +643 49 527 48 457 +644 392 218 233 238 +645 233 392 238 223 +646 178 198 197 141 +647 198 197 141 369 +648 364 290 287 528 +649 419 381 564 413 +650 92 78 79 59 +651 192 373 314 353 +652 386 406 238 423 +653 367 369 137 391 +654 437 413 419 606 +655 413 437 47 606 +656 239 252 322 255 +657 454 61 339 155 +658 34 466 425 29 +659 221 386 232 240 +660 60 64 489 484 +661 484 65 60 64 +662 212 386 218 221 +663 241 240 386 212 +664 241 205 240 212 +665 607 24 16 470 +666 620 42 37 527 +667 37 333 42 620 +668 95 87 66 69 +669 113 164 382 361 +670 410 30 432 21 +671 371 1 522 458 +672 527 47 43 40 +673 596 425 17 15 +674 393 456 160 311 +675 110 95 87 66 +676 160 311 456 516 +677 512 511 365 166 +678 353 511 365 512 +679 128 144 318 138 +680 341 130 325 308 +681 87 61 57 58 +682 419 58 564 72 +683 414 289 327 364 +684 320 378 435 94 +685 364 528 287 289 +686 212 221 205 240 +687 134 172 149 354 +688 134 172 354 184 +689 319 147 191 307 +690 589 641 606 436 +691 347 79 59 476 +692 345 79 476 92 +693 92 138 144 328 +694 86 92 144 328 +695 32 399 34 38 +696 306 309 336 310 +697 347 604 468 476 +698 347 468 79 476 +699 614 345 79 468 +700 384 310 336 270 +701 439 25 26 422 +702 196 192 314 420 +703 348 420 196 314 +704 132 143 142 318 +705 164 142 143 318 +706 386 406 423 221 +707 35 527 38 40 +708 158 354 96 162 +709 169 302 354 162 +710 334 475 564 363 +711 155 61 303 75 +712 94 353 378 339 +713 224 233 219 212 +714 214 215 204 194 +715 204 243 230 241 +716 204 230 212 241 +717 391 474 369 136 +718 286 588 528 356 +719 35 620 527 47 +720 136 474 361 565 +721 566 526 632 64 +722 490 439 11 14 +723 209 330 420 348 +724 35 527 40 47 +725 76 342 73 98 +726 77 353 102 320 +727 268 308 261 260 +728 167 155 339 378 +729 465 289 385 344 +730 255 308 260 259 +731 335 24 470 33 +732 559 24 470 335 +733 522 1 371 428 +734 347 53 496 54 +735 559 24 607 470 +736 476 347 496 54 +737 312 204 243 307 +738 230 215 243 204 +739 241 218 212 386 +740 241 238 218 386 +741 29 33 28 23 +742 23 335 559 470 +743 297 382 361 341 +744 336 611 185 331 +745 388 185 336 611 +746 353 373 102 320 +747 373 102 314 353 +748 44 527 606 610 +749 74 110 84 353 +750 610 527 606 413 +751 325 341 375 98 +752 369 136 137 391 +753 169 354 342 313 +754 274 366 279 281 +755 281 366 279 276 +756 322 313 206 308 +757 414 289 344 385 +758 114 546 367 434 +759 367 391 434 369 +760 155 163 303 61 +761 47 620 527 44 +762 384 304 552 336 +763 384 310 306 336 +764 99 378 339 94 +765 506 94 378 99 +766 365 353 512 116 +767 378 99 418 506 +768 478 23 559 470 +769 328 86 633 128 +770 265 308 268 266 +771 268 308 263 266 +772 564 419 436 58 +773 460 75 564 65 +774 339 61 99 94 +775 518 564 65 460 +776 643 216 229 392 +777 342 88 76 67 +778 26 422 11 439 +779 26 440 439 571 +780 411 161 373 441 +781 442 467 412 10 +782 350 377 24 33 +783 225 409 217 223 +784 410 377 24 350 +785 24 350 33 335 +786 371 522 523 458 +787 278 324 273 276 +788 273 324 275 276 +789 170 354 172 184 +790 169 179 354 313 +791 607 16 24 580 +792 367 391 137 118 +793 35 620 37 527 +794 548 33 461 333 +795 414 385 344 294 +796 414 289 288 344 +797 65 64 484 454 +798 93 79 78 401 +799 375 382 358 90 +800 413 575 564 594 +801 187 181 368 189 +802 358 375 90 91 +803 275 276 324 323 +804 493 270 323 275 +805 532 323 276 275 +806 324 270 323 415 +807 275 323 324 270 +808 157 331 319 336 +809 454 339 61 338 +810 527 47 507 43 +811 74 87 110 353 +812 61 353 339 155 +813 444 445 618 379 +814 173 133 160 510 +815 352 604 468 347 +816 161 181 373 348 +817 23 335 470 33 +818 181 187 374 373 +819 29 35 28 33 +820 348 187 181 373 +821 562 10 412 447 +822 10 580 503 447 +823 399 351 34 38 +824 515 592 399 32 +825 434 112 637 474 +826 134 82 96 302 +827 224 230 233 212 +828 134 302 96 354 +829 302 354 162 96 +830 376 64 60 564 +831 606 640 589 45 +832 369 137 168 141 +833 113 361 583 136 +834 197 369 168 141 +835 12 7 4 14 +836 510 181 173 171 +837 61 339 353 94 +838 369 154 170 354 +839 404 607 24 21 +840 411 374 578 441 +841 500 186 189 480 +842 535 526 632 566 +843 628 441 497 483 +844 478 23 28 559 +845 28 335 559 23 +846 93 92 78 79 +847 554 473 631 453 +848 198 178 193 141 +849 187 444 209 500 +850 226 388 336 514 +851 287 464 285 528 +852 528 301 285 372 +853 497 629 426 373 +854 394 302 70 82 +855 64 61 454 75 +856 444 587 618 445 +857 467 458 371 523 +858 371 523 520 467 +859 371 520 551 467 +860 385 465 294 292 +861 468 604 345 476 +862 584 517 63 345 +863 176 136 137 369 +864 439 440 18 571 +865 490 26 11 439 +866 324 366 227 357 +867 606 413 419 436 +868 527 48 477 507 +869 527 477 48 457 +870 527 492 48 507 +871 527 626 48 492 +872 134 354 96 158 +873 62 64 489 60 +874 52 57 370 594 +875 326 52 55 564 +876 524 425 17 19 +877 373 441 161 540 +878 373 161 140 540 +879 66 326 55 58 +880 58 326 55 564 +881 310 309 336 270 +882 324 270 336 309 +883 157 336 185 331 +884 181 411 171 161 +885 640 589 641 606 +886 537 557 621 54 +887 282 285 340 288 +888 372 285 288 340 +889 382 100 98 341 +890 502 294 465 292 +891 43 34 351 38 +892 221 240 213 205 +893 438 240 205 213 +894 425 466 524 29 +895 354 302 146 108 +896 435 426 506 629 +897 497 506 426 629 +898 187 181 374 368 +899 517 79 614 345 +900 342 90 73 98 +901 180 141 178 152 +902 178 152 141 168 +903 193 180 141 178 +904 140 161 348 510 +905 9 442 13 362 +906 442 9 13 467 +907 408 505 503 580 +908 607 580 408 16 +909 327 289 414 385 +910 372 284 283 340 +911 359 89 526 566 +912 607 539 478 470 +913 140 373 125 348 +914 328 86 92 517 +915 527 47 44 606 +916 155 163 61 353 +917 367 391 118 434 +918 338 64 61 454 +919 64 338 484 454 +920 359 89 566 338 +921 489 526 566 64 +922 448 192 378 373 +923 350 39 377 33 +924 369 137 176 168 +925 377 350 553 39 +926 325 313 375 341 +927 340 288 625 282 +928 342 313 375 325 +929 524 466 19 20 +930 425 466 19 524 +931 348 395 186 202 +932 610 44 42 45 +933 409 433 217 223 +934 217 433 529 223 +935 582 375 471 115 +936 434 474 637 369 +937 382 375 471 582 +938 98 90 382 375 +939 382 100 90 98 +940 123 105 122 85 +941 122 85 105 80 +942 43 40 34 38 +943 369 474 361 136 +944 469 452 564 460 +945 46 41 527 457 +946 415 366 274 323 +947 191 387 316 438 +948 191 387 156 316 +949 434 391 474 369 +950 502 294 344 465 +951 502 294 292 293 +952 476 59 92 79 +953 306 309 319 336 +954 528 301 464 285 +955 301 282 464 285 +956 208 449 210 379 +957 210 379 220 208 +958 551 520 10 467 +959 359 89 339 106 +960 110 353 365 116 +961 353 511 110 365 +962 118 141 145 152 +963 34 28 466 29 +964 621 347 59 54 +965 59 621 79 347 +966 342 80 122 302 +967 369 123 154 342 +968 123 85 122 342 +969 122 342 85 80 +970 450 349 612 482 +971 564 55 436 413 +972 40 38 29 34 +973 606 641 413 436 +974 28 35 335 33 +975 34 25 32 29 +976 487 548 495 479 +977 187 209 196 348 +978 461 479 430 495 +979 311 513 509 186 +980 395 311 348 186 +981 187 196 209 444 +982 485 540 426 373 +983 21 580 24 447 +984 412 447 21 562 +985 412 562 21 446 +986 447 580 24 10 +987 46 527 610 413 +988 229 392 216 222 +989 323 281 366 274 +990 281 301 274 323 +991 599 625 429 282 +992 608 25 32 34 +993 372 288 284 340 +994 227 324 190 308 +995 373 196 348 187 +996 425 25 34 29 +997 628 448 373 591 +998 591 448 373 398 +999 477 43 41 527 +1000 80 71 81 302 +1001 457 477 41 527 +1002 647 487 430 479 +1003 628 373 497 441 +1004 578 628 441 374 +1005 410 24 335 350 +1006 393 311 160 150 +1007 367 118 137 141 +1008 343 488 356 396 +1009 87 72 61 58 +1010 488 588 356 396 +1011 476 54 59 347 +1012 94 353 61 77 +1013 110 353 87 107 +1014 251 245 322 201 +1015 245 179 322 201 +1016 11 422 486 14 +1017 287 588 464 528 +1018 10 467 412 551 +1019 13 551 412 467 +1020 371 467 551 13 +1021 551 10 8 412 +1022 113 164 361 136 +1023 425 25 15 26 +1024 140 348 125 160 +1025 451 588 528 286 +1026 180 152 145 141 +1027 607 16 539 470 +1028 374 570 400 373 +1029 373 374 556 400 +1030 374 373 556 628 +1031 441 628 578 483 +1032 497 642 418 629 +1033 167 89 106 339 +1034 346 440 390 521 +1035 369 123 342 375 +1036 583 382 498 361 +1037 564 75 72 61 +1038 564 61 64 75 +1039 345 517 79 92 +1040 533 529 223 222 +1041 498 582 576 375 +1042 575 376 609 49 +1043 412 10 8 447 +1044 561 472 549 468 +1045 239 322 252 231 +1046 397 12 4 14 +1047 367 369 434 576 +1048 206 313 322 179 +1049 322 179 313 354 +1050 12 2 4 7 +1051 346 638 26 608 +1052 66 87 57 58 +1053 72 58 564 61 +1054 322 207 231 239 +1055 201 354 322 207 +1056 239 255 322 201 +1057 533 402 529 222 +1058 60 518 564 65 +1059 11 486 12 14 +1060 118 168 141 152 +1061 60 376 564 518 +1062 576 375 582 115 +1063 515 34 399 351 +1064 334 564 64 363 +1065 311 331 150 305 +1066 473 538 597 519 +1067 564 594 575 475 +1068 36 30 432 410 +1069 343 396 356 279 +1070 281 279 356 396 +1071 281 274 301 356 +1072 486 7 14 422 +1073 642 153 585 629 +1074 153 642 628 629 +1075 503 447 8 10 +1076 461 430 620 416 +1077 493 270 275 280 +1078 275 493 532 323 +1079 532 493 282 323 +1080 461 495 430 416 +1081 493 532 280 275 +1082 389 381 47 413 +1083 49 413 626 527 +1084 500 189 186 181 +1085 498 382 582 375 +1086 410 30 24 377 +1087 30 410 36 377 +1088 366 265 279 272 +1089 608 34 32 31 +1090 527 40 43 38 +1091 46 527 41 38 +1092 43 527 38 41 +1093 597 639 7 486 +1094 306 298 336 331 +1095 11 26 15 543 +1096 554 11 15 543 +1097 416 430 620 649 +1098 291 290 364 327 +1099 637 498 375 361 +1100 39 548 33 461 +1101 422 634 25 543 +1102 583 582 382 113 +1103 367 114 118 141 +1104 473 422 11 554 +1105 178 197 168 141 +1106 375 369 123 115 +1107 91 123 115 375 +1108 377 350 36 553 +1109 173 181 516 186 +1110 110 95 107 87 +1111 353 107 163 87 +1112 46 527 42 610 +1113 500 209 348 202 +1114 334 61 564 57 +1115 510 103 140 161 +1116 160 104 140 133 +1117 486 11 473 422 +1118 336 611 331 514 +1119 576 434 637 369 +1120 29 466 524 20 +1121 366 279 265 258 +1122 366 279 258 274 +1123 89 484 338 454 +1124 462 621 568 534 +1125 133 104 140 103 +1126 462 534 568 531 +1127 521 440 390 563 +1128 383 440 563 390 +1129 141 154 170 369 +1130 141 193 369 170 +1131 173 181 510 516 +1132 348 510 181 516 +1133 324 366 276 272 +1134 415 324 366 323 +1135 477 527 507 43 +1136 26 25 440 346 +1137 430 333 42 479 +1138 460 452 564 75 +1139 31 515 32 592 +1140 181 189 187 500 +1141 389 527 413 47 +1142 413 389 626 527 +1143 376 590 49 575 +1144 331 611 185 508 +1145 223 392 407 219 +1146 223 233 392 219 +1147 538 648 597 519 +1148 597 648 538 486 +1149 557 537 568 499 +1150 553 39 461 416 +1151 290 528 451 287 +1152 554 453 332 560 +1153 601 467 458 9 +1154 623 525 535 566 +1155 566 525 535 526 +1156 378 106 431 418 +1157 53 496 352 347 +1158 564 300 419 72 +1159 564 452 300 72 +1160 2 6 7 486 +1161 421 451 528 286 +1162 451 528 588 287 +1163 409 595 433 491 +1164 79 621 78 401 +1165 401 621 78 555 +1166 78 537 555 621 +1167 599 340 282 301 +1168 493 599 282 301 +1169 430 620 42 333 +1170 565 498 112 637 +1171 583 498 112 565 +1172 599 429 536 282 +1173 599 625 459 429 +1174 543 554 332 15 +1175 474 112 637 565 +1176 364 290 528 327 +1177 548 461 479 333 +1178 461 333 430 479 +1179 383 390 346 440 +1180 65 60 64 564 +1181 65 64 75 564 +1182 383 638 346 390 +1183 380 468 614 549 +1184 532 282 276 323 +1185 157 331 504 150 +1186 89 454 338 339 +1187 167 454 89 339 +1188 8 5 10 551 +1189 5 520 10 551 +1190 492 626 545 389 +1191 389 626 545 469 +1192 37 33 35 29 +1193 615 568 499 557 +1194 500 186 480 202 +1195 54 56 53 496 +1196 294 295 291 385 +1197 295 291 385 327 +1198 295 294 292 385 +1199 474 637 361 565 +1200 497 373 426 540 +1201 40 29 28 34 +1202 535 525 581 526 +1203 328 92 79 517 +1204 496 56 352 604 +1205 459 536 646 493 +1206 459 429 624 536 +1207 493 536 280 532 +1208 25 346 26 608 +1209 351 399 41 38 +1210 43 41 38 351 +1211 527 413 47 606 +1212 308 252 322 231 +1213 308 255 322 252 +1214 256 231 252 308 +1215 256 308 259 247 +1216 21 30 24 410 +1217 21 30 562 24 +1218 315 621 555 568 +1219 217 219 223 407 +1220 225 223 219 233 +1221 407 217 529 223 +1222 381 452 300 564 +1223 595 635 433 491 +1224 414 385 291 327 +1225 416 39 461 495 +1226 461 39 548 495 +1227 461 548 479 495 +1228 301 282 281 464 +1229 301 282 285 340 +1230 315 621 568 462 +1231 372 289 288 285 +1232 289 288 285 414 +1233 431 153 106 378 +1234 55 641 589 436 +1235 651 572 638 608 +1236 564 452 72 75 +1237 573 534 567 613 +1238 567 645 600 534 +1239 499 568 577 537 +1240 414 327 291 364 +1241 561 549 614 468 +1242 338 489 566 64 +1243 89 484 489 338 +1244 385 294 465 344 +1245 445 196 444 209 +1246 209 550 444 427 +1247 490 14 11 12 +1248 490 18 14 12 +1249 597 648 486 7 +1250 486 639 7 422 +1251 639 473 597 631 +1252 529 491 616 533 +1253 435 320 125 373 +1254 616 491 529 541 +1255 497 628 642 629 +1256 46 52 413 602 +1257 623 359 566 338 +1258 497 506 629 418 +1259 99 359 623 338 +1260 65 64 454 75 +1261 209 617 550 427 +1262 86 328 144 128 +1263 570 187 374 368 +1264 403 86 633 328 +1265 601 522 458 523 +1266 604 352 472 56 +1267 273 312 319 324 +1268 380 614 63 549 +1269 561 549 63 614 +1270 623 525 566 359 +1271 359 525 566 526 +1272 566 89 526 489 +1273 113 382 358 471 +1274 582 471 382 113 +1275 523 467 458 601 +1276 268 308 260 263 +1277 374 628 556 578 +1278 498 582 382 583 +1279 586 645 534 557 +1280 361 176 369 136 +1281 277 356 274 279 +1282 576 637 375 369 +1283 637 375 369 361 +1284 373 556 569 400 +1285 556 373 569 628 +1286 447 562 24 21 +1287 47 492 527 507 +1288 495 39 548 487 +1289 572 608 651 650 +1290 541 619 542 574 +1291 27 562 21 30 +1292 21 446 562 27 +1293 517 328 614 79 +1294 545 530 622 575 +1295 522 371 523 558 +1296 523 371 520 558 +1297 471 91 115 375 +1298 578 127 628 556 +1299 127 153 628 556 +1300 641 413 55 52 +1301 55 564 436 58 +1302 564 334 57 594 +1303 55 641 436 413 +1304 575 413 49 594 +1305 15 17 596 560 +1306 521 440 563 571 +1307 632 581 62 526 +1308 285 372 301 340 +1309 290 451 528 421 +1310 326 57 564 58 +1311 205 212 241 204 +1312 564 452 469 381 +1313 239 322 207 201 +1314 223 392 529 407 +1315 381 564 413 469 +1316 395 513 311 186 +1317 389 469 413 626 +1318 136 361 583 565 +1319 586 645 567 534 +1320 32 25 608 346 +1321 369 367 137 141 +1322 469 575 545 622 +1323 593 543 634 422 +1324 373 569 628 591 +1325 556 569 153 628 +1326 196 187 373 570 +1327 167 454 339 155 +1328 590 626 575 530 +1329 536 493 282 532 +1330 133 140 160 510 +1331 376 363 64 564 +1332 209 427 444 587 +1333 571 440 563 383 +1334 498 375 576 637 +1335 531 534 568 579 +1336 534 568 557 621 +1337 218 392 643 238 +1338 568 555 577 537 +1339 475 609 363 49 +1340 363 609 475 564 +1341 393 311 150 305 +1342 19 425 17 596 +1343 596 17 603 560 +1344 522 428 371 558 +1345 127 628 497 483 +1346 492 48 545 626 +1347 21 607 24 580 +1348 132 117 318 128 +1349 633 132 547 142 +1350 437 381 419 413 +1351 419 381 437 300 +1352 173 181 186 171 +1353 405 613 600 534 +1354 632 526 62 64 +1355 489 484 64 338 +1356 600 54 53 621 +1357 29 20 28 466 +1358 20 28 466 443 +1359 49 48 626 590 +1360 63 345 614 380 +1361 584 345 63 380 +1362 470 607 559 478 +1363 28 23 22 20 +1364 478 23 22 28 +1365 473 422 554 631 +1366 555 537 568 621 +1367 18 490 14 439 +1368 596 17 19 603 +1369 571 440 18 521 +1370 542 491 616 541 +1371 534 568 615 557 +1372 534 568 579 615 +1373 392 222 229 238 +1374 626 48 530 590 +1375 238 406 229 423 +1376 629 585 642 418 +1377 418 506 629 378 +1378 378 431 629 418 +1379 153 448 628 591 +1380 591 569 628 153 +1381 550 209 500 627 +1382 515 31 32 34 +1383 209 627 550 617 +1384 569 556 153 400 +1385 645 621 557 54 +1386 529 491 533 223 +1387 601 1 458 522 +1388 522 601 1 3 +1389 359 339 99 106 +1390 338 99 359 339 +1391 49 575 626 413 +1392 473 597 631 453 +1393 605 564 518 460 +1394 222 392 402 529 +1395 113 382 583 361 +1396 33 335 28 23 +1397 370 52 594 46 +1398 408 505 580 607 +1399 413 640 602 641 +1400 630 376 564 609 +1401 49 376 609 363 +1402 363 376 609 564 +1403 393 456 311 305 +1404 218 221 386 643 +1405 643 386 423 221 +1406 141 123 369 367 +1407 498 382 375 361 +1408 474 637 369 361 +1409 558 371 520 551 +1410 558 428 371 551 +1411 374 441 411 373 +1412 422 25 26 543 +1413 25 17 15 634 +1414 606 44 610 45 +1415 367 115 369 576 +1416 367 576 546 115 +1417 636 573 567 613 +1418 615 51 579 573 +1419 50 51 615 636 +1420 55 413 564 52 +1421 594 52 413 46 +1422 564 326 52 57 +1423 367 434 546 576 +1424 208 449 379 445 +1425 379 445 544 208 +1426 26 439 440 25 +1427 622 575 605 469 +1428 636 586 567 573 +1429 573 586 567 534 +1430 599 625 340 283 +1431 605 630 518 564 +1432 171 510 181 161 +1433 32 29 38 34 +1434 402 216 392 222 +1435 223 222 392 238 +1436 389 492 527 47 +1437 389 492 626 527 +1438 577 555 78 537 +1439 315 621 401 555 +1440 15 598 634 560 +1441 634 17 15 560 +1442 481 142 328 633 +1443 128 328 144 138 +1444 413 610 640 606 +1445 640 606 610 45 +1446 379 449 444 445 +1447 187 449 196 444 +1448 445 449 444 196 +1449 605 564 460 469 +1450 575 564 605 469 +1451 541 200 619 574 +1452 564 436 419 413 +1453 517 482 63 614 +1454 154 369 141 123 +1455 583 498 565 361 +1456 498 361 637 565 +1457 622 530 630 575 +1458 21 30 432 27 +1459 173 510 160 516 +1460 311 160 348 516 +1461 485 140 540 373 +1462 21 505 580 447 +1463 490 26 439 571 +1464 379 544 220 208 +1465 348 516 181 186 +1466 186 509 311 516 +1467 209 202 627 617 +1468 433 635 529 491 +1469 430 42 620 44 +1470 649 430 620 44 +1471 529 635 541 491 +1472 404 24 410 21 +1473 404 410 24 335 +1474 89 338 359 339 +1475 450 328 482 517 +1476 517 328 482 614 +1477 78 59 537 621 +1478 588 396 281 356 +1479 286 488 588 356 +1480 424 543 593 422 +1481 463 607 408 16 +1482 389 381 413 469 +1483 413 469 575 626 +1484 626 469 575 545 +1485 554 11 543 422 +1486 459 624 646 536 +1487 332 543 593 424 +1488 631 554 424 422 +1489 153 431 629 378 +1490 545 48 530 626 +1491 626 530 545 575 +1492 59 621 78 79 +1493 160 510 348 516 +1494 626 590 575 49 +1495 576 434 112 637 +1496 498 576 112 637 +1497 346 651 638 608 +1498 13 442 412 362 +1499 13 467 412 442 +1500 132 142 633 128 +1501 184 180 172 170 +1502 631 332 424 554 +1503 531 573 579 51 +1504 521 571 563 18 +1505 599 625 282 340 +1506 622 630 605 575 +1507 562 442 362 412 +1508 193 180 170 141 +1509 50 644 636 615 +1510 443 466 20 19 +1511 616 542 533 491 +1512 413 594 564 52 +1513 621 53 600 405 +1514 362 562 446 27 +1515 403 547 321 481 +1516 403 481 321 329 +1517 562 442 412 10 +1518 493 459 536 599 +1519 493 599 536 282 +1520 450 86 328 517 +1521 413 602 610 46 +1522 29 23 28 20 +1523 223 409 433 491 +1524 621 59 537 54 +1525 13 362 412 446 +1526 439 422 11 14 +1527 639 473 631 422 +1528 450 612 584 517 +1529 450 482 612 517 +1530 413 641 602 52 +1531 447 10 24 562 +1532 531 573 534 579 +1533 380 345 468 604 +1534 587 427 444 618 +1535 613 567 600 534 +1536 218 386 238 643 +1537 643 238 423 386 +1538 347 496 352 604 +1539 63 345 517 614 +1540 584 612 63 517 +1541 629 431 585 418 +1542 153 431 585 629 +1543 463 539 478 607 +1544 463 539 607 16 +1545 564 609 475 575 +1546 533 529 402 616 +1547 376 630 564 518 +1548 645 54 600 621 +1549 380 468 472 604 +1550 604 468 472 352 +1551 380 468 549 472 +1552 570 187 373 374 +1553 606 413 641 640 +1554 413 610 602 640 +1555 458 467 13 9 +1556 467 458 13 371 +1557 11 422 26 543 +1558 25 17 425 15 +1559 646 536 280 493 +1560 646 624 280 536 +1561 647 430 44 42 +1562 618 544 220 379 +1563 648 6 486 7 +1564 648 6 538 486 +1565 403 633 547 481 +1566 403 328 633 481 +1567 483 127 628 578 +1568 486 7 12 14 +1569 53 56 352 496 +1570 340 288 284 625 +1571 283 340 284 625 +1572 561 352 472 468 +1573 86 450 328 403 +1574 329 403 481 328 +1575 455 288 284 372 +1576 501 288 284 455 +1577 376 530 575 630 +1578 630 376 609 575 +1579 430 479 42 647 +1580 621 405 600 534 +1581 22 28 20 443 +1582 643 238 229 423 +1583 481 633 547 142 +1584 558 428 551 652 +1585 509 611 331 508 +1586 513 514 331 611 +1587 509 513 331 611 +1588 601 9 1 3 +1589 289 288 344 501 +1590 515 32 399 34 +1591 403 321 349 329 +1592 392 229 643 238 +1593 618 445 544 379 +1594 618 587 544 445 +1595 531 613 534 573 +1596 629 153 448 628 +1597 538 473 597 486 +1598 597 473 639 486 +1599 650 31 608 346 +1600 607 505 580 21 +1601 288 455 289 372 +1602 289 455 288 501 +1603 376 530 590 575 +1604 49 594 475 575 +1605 356 279 281 274 +1606 550 209 444 500 +1607 362 412 446 562 +1608 529 433 491 223 +1609 455 372 284 283 +1610 465 501 455 289 +1611 465 289 344 501 +1612 445 209 444 587 +1613 153 642 127 628 +1614 294 385 291 414 +1615 283 625 459 599 +1616 613 531 51 573 +1617 636 573 613 51 +1618 557 621 568 537 +1619 558 551 520 5 +1620 500 209 202 627 +1621 635 200 541 574 +1622 595 200 635 574 +1623 558 652 551 5 +1624 534 579 573 615 +1625 605 575 630 564 +1626 31 346 32 608 +1627 631 424 639 422 +1628 383 346 638 26 +1629 469 575 564 413 +1630 15 560 332 598 +1631 15 554 332 560 +1632 586 557 534 615 +1633 573 586 534 615 +1634 332 543 598 593 +1635 543 332 598 15 +1636 609 575 564 630 +1637 554 631 332 453 +1638 424 554 543 422 +1639 608 346 651 650 +1640 487 495 430 479 +1641 645 621 534 557 +1642 645 621 600 534 +1643 542 491 541 574 +1644 541 635 574 491 +1645 636 644 586 573 +1646 573 586 615 644 +1647 543 634 598 593 +1648 497 127 642 628 +1649 598 543 15 634 +1650 25 15 543 634 +1651 473 519 597 453 +1652 595 574 635 491 +1653 636 51 615 573 +1654 644 573 636 615 +$EndElements diff --git a/test/user/testdata/shark_41_ascii_gmshApp.xml b/test/user/testdata/shark_41_ascii_gmshApp.xml new file mode 100644 index 00000000..97ba9c3d --- /dev/null +++ b/test/user/testdata/shark_41_ascii_gmshApp.xml @@ -0,0 +1,25 @@ + + diff --git a/test/user/testdata/shark_41_ascii_missing_element.msh b/test/user/testdata/shark_41_ascii_missing_element.msh new file mode 100644 index 00000000..83b7a87f --- /dev/null +++ b/test/user/testdata/shark_41_ascii_missing_element.msh @@ -0,0 +1,2972 @@ +$MeshFormat +4.1 0 8 +$EndMeshFormat +$Entities +0 0 0 1 +0 -0.07334360000000001 -0.08523339999999999 -0.0005566629999999989 0.07028570000000001 0.0819076 0.0752128 0 0 +$EndEntities +$Nodes +1 652 1 652 +3 0 0 652 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +-0.07334359999999999 0.08167480000000001 0.056402 +-0.07291259999999999 0.0537921 0.00170478 +-0.072634 0.0799069 0.0578949 +-0.0715817 0.0520377 0.00292576 +-0.0701949 0.08025690000000001 0.0450431 +-0.06876980000000001 0.060971 0.00326551 +-0.06778000000000001 0.060358 0.00473741 +-0.06727959999999999 0.08092489999999999 0.0425553 +-0.0658074 0.0806443 0.0552302 +-0.064933 0.0788176 0.0453762 +-0.0636555 0.0610198 0.00141989 +-0.0636111 0.0566004 -0.000556663 +-0.0636791 0.0819076 0.0524468 +-0.0623445 0.0580268 0.00335683 +-0.0624856 0.06710579999999999 0.00581638 +-0.0601398 0.0781111 0.0317589 +-0.0599443 0.0685632 0.009924489999999999 +-0.0592787 0.0571239 0.00105116 +-0.0587906 0.07199990000000001 0.0117948 +-0.0575605 0.0730663 0.016213 +-0.057624 0.0811803 0.0403639 +-0.0572339 0.0769387 0.0223219 +-0.0559974 0.0749629 0.0235691 +-0.0542321 0.0763209 0.0344665 +-0.0540672 0.0649483 0.008218130000000001 +-0.0541685 0.06611350000000001 0.00437935 +-0.0532966 0.0805356 0.0466758 +-0.0517252 0.07611850000000001 0.0183218 +-0.0505257 0.06887699999999999 0.0152572 +-0.0503803 0.07726379999999999 0.0406423 +-0.0472855 0.0641041 0.00381053 +-0.0469016 0.0648796 0.00821733 +-0.0474599 0.07272679999999999 0.0265623 +-0.0464733 0.070912 0.0103373 +-0.0444756 0.07556740000000001 0.0221683 +-0.0440208 0.07743129999999999 0.0371107 +-0.0434135 0.0685101 0.0213943 +-0.0425401 0.0668787 0.0159114 +-0.0405353 0.07301630000000001 0.0309862 +-0.0386417 0.073548 0.0160682 +-0.037401 0.0664899 0.0122191 +-0.0358693 0.06894450000000001 0.0243885 +-0.0351058 0.06877709999999999 0.0124837 +-0.0333614 0.07116500000000001 0.0238503 +-0.0325564 0.0696271 0.024504 +-0.032455 0.0625178 0.0200737 +-0.0305469 0.0729973 0.0173921 +-0.0276941 0.06523859999999999 0.0128238 +-0.0272717 0.0628782 0.0141328 +-0.0263428 0.00735496 0.00505748 +-0.0256055 0.00658056 0.00327552 +-0.0252856 0.0610141 0.0227762 +-0.0250237 -0.00678856 0.00359213 +-0.0242889 -0.00589458 0.00589675 +-0.0216872 0.0639735 0.0255561 +-0.0215721 -0.0119744 0.00619585 +-0.0195136 0.0542304 0.0216195 +-0.0168343 0.06495339999999999 0.0236547 +-0.0161373 -0.00420129 0.00881529 +-0.0148726 0.0585475 0.0106707 +-0.0140647 0.0517836 0.0159197 +-0.0142986 0.0543801 0.0051496 +-0.0139611 -0.0178642 0.00651265 +-0.0139803 0.0554055 0.0115694 +-0.0124373 0.0606817 0.0122622 +-0.0127423 0.0580719 0.0285553 +-0.0127412 -0.07042320000000001 0.0234664 +-0.0126173 -0.0801905 0.022154 +-0.0125269 0.0592002 0.0346418 +-0.0122498 -0.080596 0.0191154 +-0.0121442 -0.0691943 0.0191352 +-0.0123618 0.0658492 0.0197519 +-0.0121018 -0.063334 0.0245151 +-0.0118539 0.0462485 0.0243954 +-0.0111067 0.0637388 0.0161162 +-0.0110042 -0.0624802 0.0276395 +-0.0109072 0.046219 0.0183571 +-0.0107037 -0.000325242 0.00950432 +-0.010183 -0.0121386 0.00674337 +-0.009774420000000001 -0.0638147 0.0162637 +-0.0097669 -0.06993340000000001 0.0156591 +-0.00942656 -0.0836042 0.0182705 +-0.009320999999999999 -0.0852334 0.0216727 +-0.00803502 0.0401179 0.0263407 +-0.00857808 -0.0579335 0.0163943 +-0.007931580000000001 -0.0190616 0.0121625 +-0.00782675 0.0573514 0.028038 +-0.00773028 -0.0620746 0.0302044 +-0.00764665 0.0537773 0.00961295 +-0.00721562 -0.0507362 0.0224357 +-0.00717408 -0.0528249 0.0179333 +-0.00651588 -0.00739691 0.013024 +-0.00691116 -0.00014073 0.00823716 +-0.00661131 0.044183 0.0123 +-0.00658663 0.0535365 0.0326225 +-0.00630954 -0.08506569999999999 0.0194796 +-0.00616497 -0.0797841 0.0261073 +-0.00582999 -0.0494502 0.0287705 +-0.00563359 0.0476479 0.00934546 +-0.00506609 -0.0425596 0.0250833 +-0.00453974 -0.0405694 0.0173853 +-0.00447266 0.0319291 0.0205877 +-0.00434886 0.0267225 0.00648417 +-0.00418386 0.0253438 0.008421959999999999 +-0.0041733 -0.0606038 0.0122716 +-0.00385183 0.0479538 0.00869149 +-0.00333705 0.051389 0.031593 +-0.00333565 -0.06938809999999999 0.0119551 +-0.00333748 -0.0650683 0.0110291 +-0.00292457 0.0475597 0.0319288 +-0.00280471 -0.0353375 0.0238411 +-0.00273019 -0.0493159 0.0135756 +-0.00255346 -0.0452657 0.0126112 +-0.00249178 -0.0598565 0.010934 +-0.00247351 -0.0533955 0.0149632 +-0.00280465 0.0288144 0.0300227 +-0.00225175 -0.030519 0.0236922 +-0.00205777 -0.0595101 0.00715068 +-0.0018581 -0.0627033 0.0116048 +-0.00150112 -0.0384203 0.0313885 +-0.00143547 -0.0337232 0.0176227 +-0.00136747 -0.062725 0.0150152 +-0.000884775 -0.0587825 0.0143119 +-0.000624659 -0.0247814 0.0257906 +-0.000489974 0.0225414 0.0188523 +-6.05566e-05 0.0171338 0.0234086 +0.00150381 0.0360475 0.00675461 +0.000282178 -0.0241462 0.0174969 +0.000347869 -0.06752370000000001 0.0324883 +0.000429839 -0.0422219 0.0349169 +0.00028168 -0.0273698 0.0312235 +0.000952705 -0.0267391 0.0143612 +0.00105244 0.0186951 0.00689988 +0.0011109 -0.0779453 0.014663 +0.00137887 0.00842564 0.0258445 +0.00107238 -0.0462225 0.00980545 +0.00158113 -0.0561697 0.005809 +0.00165921 -0.0142314 0.0114909 +0.00169065 -0.00330978 0.027848 +0.0017282 0.0264299 0.00972258 +0.00196109 -0.062067 0.0125082 +0.00198494 -0.0249792 0.0122768 +0.00206797 -0.0322322 0.0125632 +0.00219287 -0.00991015 0.0199027 +0.00223228 -0.065619 0.00972103 +0.00226787 -0.06664 0.0139131 +0.00233081 0.009707510000000001 0.0349608 +0.0023033 -0.0550711 0.0357611 +0.00284591 -0.06958739999999999 0.0109337 +0.00313658 0.0123831 0.0152878 +0.00325266 -0.000639164 0.0164744 +0.00354678 -0.0651674 0.00553443 +0.00434877 0.0392681 0.00656793 +0.0034004 -0.0624097 0.0143354 +0.00410027 0.052311 0.0146156 +0.00425687 -0.0110681 0.0377954 +0.0043501 -0.0020508 0.015115 +0.00444422 -0.0785667 0.0168482 +0.00471578 -0.008727459999999999 0.0133588 +0.00486541 0.0192794 0.0102326 +0.00475235 0.0259901 0.00777948 +0.00497525 -0.0797755 0.0244877 +0.0052286 0.0545416 0.0234287 +0.00513856 -0.0361953 0.00904286 +0.00543656 -0.016404 0.0117933 +0.00521097 0.0361763 0.0357574 +0.00563068 0.0458779 0.0101474 +0.00602624 -0.0598053 0.00448538 +0.00669265 -0.0730234 0.0300997 +0.00671975 -0.0647944 0.0149968 +0.00743572 0.0219428 0.00498754 +0.00806977 -0.06766220000000001 0.0106835 +0.008580020000000001 0.0185363 0.00804532 +0.00900922 -0.0527441 0.0382868 +0.00967438 -0.0310472 0.0412759 +0.009690270000000001 -0.0470756 0.00574739 +0.009825469999999999 -0.0777201 0.0238208 +0.010337 -0.0646559 0.00738197 +0.0103691 -0.0715108 0.0301524 +0.0108524 -0.06519229999999999 0.0107074 +0.0112352 0.0223598 0.00496048 +0.0115762 0.0360388 0.034027 +0.011811 0.0150563 0.0411225 +0.0119389 -0.07108730000000001 0.0142927 +0.011481 0.000850754 0.00890493 +0.0122581 0.0177891 0.00726338 +0.0126044 0.0285097 0.0071727 +0.0126077 -0.0410848 0.00487059 +0.01325 0.0245576 0.00385279 +0.0133342 -0.0301914 0.00695184 +0.0134526 -0.00467313 0.044297 +0.0140263 0.0415073 0.0128325 +0.0139319 -0.0627506 0.0126489 +0.0144402 0.0213321 0.0408733 +0.0145153 -0.0120242 0.00709154 +0.0145254 0.0314471 0.00762861 +0.0143606 -0.0539791 0.00638859 +0.0153705 -0.0588177 0.00913193 +0.0158483 0.0424843 0.0267153 +0.0161677 0.0082135 0.0752128 +0.0160709 -0.0693691 0.0267104 +0.0163112 0.021127 0.00658374 +0.0163956 0.0418119 0.0180916 +0.0166653 0.00513625 0.0449469 +0.0171438 -0.009394380000000001 0.0462661 +0.0174416 -0.0497054 0.0373642 +0.0174198 -0.06569369999999999 0.0159871 +0.0177387 0.0346114 0.0053358 +0.0178439 0.0247259 0.00729322 +0.018247 0.0346901 0.00258831 +0.0182074 -0.0318958 0.0424624 +0.0183988 -0.00142899 0.0496692 +0.0188182 -0.018825 0.0447569 +0.0188285 0.0147456 0.0461032 +0.0188626 0.015416 0.041072 +0.0190811 -0.00419709 0.06868580000000001 +0.0195945 0.0084326 0.064095 +0.0197498 -0.00217441 0.0583864 +0.0198208 0.00539755 0.0587622 +0.0200137 0.0324539 0.00354185 +0.020151 -0.0145671 0.0500049 +0.0203386 -0.00326709 0.07024469999999999 +0.0209148 0.00523036 0.0681576 +0.0208447 0.0121045 0.0546374 +0.0209724 0.009706330000000001 0.0633876 +0.020604 -0.0121123 0.00591309 +0.0212498 -0.0289526 0.00565549 +0.0216078 -0.0380775 0.00479088 +0.0216875 -0.00997672 0.0619769 +0.0220658 0.00705093 0.0456869 +0.0223002 -0.0558455 0.0110476 +0.0223137 -0.0154618 0.0494217 +0.0229336 0.00417573 0.0589573 +0.0231427 0.0278288 0.0125965 +0.0231751 0.027241 0.0309726 +0.0233259 0.0160686 0.00756079 +0.0234095 0.0318943 0.0199392 +0.0234462 -0.00393483 0.0583985 +0.0235915 -0.0597066 0.0170609 +0.0240196 -0.0108777 0.0466362 +0.024123 -0.00330273 0.0464733 +0.0242099 -0.0321428 0.0398591 +0.0244244 0.00347947 0.0416421 +0.024564 -0.0175604 0.0433407 +0.0253979 -0.0453083 0.0344803 +0.0256103 0.0267734 0.0284514 +0.0259312 -0.0445208 0.00878379 +0.025959 -0.0133125 0.00624018 +0.0265967 -0.0369666 0.00635268 +0.0273245 -0.0066598 0.0412078 +0.0277597 -0.0467651 0.0304517 +0.0275944 -0.0515878 0.0207552 +0.0282687 0.0208205 0.0174814 +0.0290859 0.0112094 0.012597 +0.0293048 -0.0474855 0.0256026 +0.0296506 -0.0466043 0.0156453 +0.0304236 0.0134394 0.031696 +0.0304518 -0.0291908 0.00746031 +0.03126 -0.044124 0.016095 +0.0321715 -0.043346 0.0242104 +0.0322352 -0.0402733 0.0141242 +0.0323149 0.01052 0.0200521 +0.0324768 -0.0397188 0.0271188 +0.0325431 -0.0291932 0.0340382 +0.0332479 -0.0329826 0.0117351 +0.0338676 -0.0346121 0.0252676 +0.0341522 -0.00293196 0.033596 +0.0341882 -0.0361716 0.0179088 +0.0344969 -0.0256263 0.0309923 +0.0345138 -0.00958586 0.0123416 +0.0348872 -0.0128566 0.0339912 +0.0349524 -0.0273994 0.0177976 +0.0349556 -0.000677158 0.0209767 +0.0350004 -0.028049 0.008761420000000001 +0.0353194 -0.0100316 0.0154749 +0.0354214 -0.0195455 0.0173172 +0.0355775 -0.0309821 0.0107592 +0.0360305 -0.0150581 0.0232372 +0.0363938 -0.0285041 0.0132933 +0.0374738 -0.00607371 0.0123945 +0.041317 -0.0210454 0.0131228 +0.0425886 -0.0120136 0.0129537 +0.0475164 -0.00753527 0.00853843 +0.0492593 -0.00704914 0.009380670000000001 +0.0496752 -0.0170405 0.0106038 +0.0498676 -0.0259318 0.00619626 +0.052402 -0.022331 0.00866719 +0.0516897 -0.011391 0.0103437 +0.0559595 -0.0106346 0.00698866 +0.0596531 -0.0214295 0.0059579 +0.066312 -0.0158462 0.00759335 +0.0672852 -0.00331292 0.00667068 +0.0687074 -0.0027598 0.00829441 +0.0687083 -0.008451500000000001 0.00881385 +0.07028570000000001 -0.00694567 0.00665748 +0.02471 0.00101921 0.00688758 +0.00641783 -0.0341512 0.0233596 +0.024018 0.00854392 0.00722419 +0.0251696 0.009421270000000001 0.00784613 +-0.019815 0.0686939 0.0189821 +0.0416697 -0.017118 0.00864259 +-0.00440288 -0.06984319999999999 0.0205811 +-0.0033606 0.0600219 0.0217676 +0.0268544 0.00322876 0.008082499999999999 +0.00855449 0.0107052 0.00928038 +0.0219179 0.00585482 0.0121236 +0.0199208 0.0175811 0.0336776 +0.0210521 -0.0362113 0.0256186 +0.0339797 -0.00194129 0.0163861 +0.03202 0.000337126 0.0126992 +0.0119633 0.0163586 0.0147908 +0.0248778 0.0056119 0.0321775 +0.00892971 -0.0563678 0.0287948 +0.0174837 0.027107 0.0210333 +-0.0170518 0.00346089 0.00554363 +0.0144974 -0.0120686 0.0314959 +0.00336155 -0.00103205 0.0364574 +0.00707711 -0.0204903 0.0185209 +0.010517 -0.00309481 0.0232445 +-0.00559352 0.0373259 0.0172753 +-0.00523735 -0.0230725 0.0111224 +0.0151072 -0.0538804 0.0213778 +0.0347571 -0.0188174 0.0105515 +0.0278657 -0.0183642 0.0156758 +-0.00338013 -0.0543805 0.0329679 +-0.0196332 0.0593213 0.0251138 +0.06481629999999999 -0.0143432 0.00627944 +-0.00336175 -0.0187472 0.00979996 +-0.0059938 -0.0214388 0.00941436 +0.0204933 0.0262773 0.00994486 +0.0153554 0.00838654 0.0105168 +-0.064082 0.064994 0.00682263 +-0.0406296 0.0703091 0.0249838 +-0.0197677 0.0563929 0.0156108 +-0.0506931 0.0781816 0.0304629 +0.0171972 -0.00100568 0.011485 +0.0314619 -0.0225976 0.00774901 +-0.00980694 0.0515267 0.0104574 +-0.00435185 0.0493969 0.0137744 +0.0449063 -0.0117353 0.00859937 +0.00159087 -0.0450385 0.027858 +-0.00469537 -0.06372510000000001 0.0233918 +0.0424219 -0.0285632 0.00857374 +0.0603894 -0.00835109 0.009350529999999999 +-0.0147113 -0.0156046 0.009183759999999999 +-0.0528157 0.0611754 0.00480955 +-0.0173765 -0.008871489999999999 0.00520522 +0.0108104 0.02268 0.0130558 +-0.00899905 -0.0208443 0.00915416 +-0.0449914 0.0768094 0.0302276 +-0.0408502 0.06658 0.008368489999999999 +-0.0199988 -0.0118916 0.004906 +0.00337131 0.0455887 0.0238561 +0.00477413 -0.0721541 0.0211645 +-0.00344193 -0.049333 0.032475 +0.0427245 -0.0268877 0.00738607 +0.0272704 -0.0238375 0.00669928 +-0.00610544 -0.0476638 0.0181008 +-0.00760153 0.0503529 0.00747858 +0.0131109 -0.0422224 0.0405109 +0.00214561 -0.0490294 0.0151357 +-0.0598224 0.0805424 0.0511855 +-0.0204542 0.0588165 0.013102 +0.059357 -0.0190886 0.00813027 +-0.00100716 0.0422264 0.0325724 +0.0325535 -0.0244764 0.012522 +-0.000431427 -0.0574818 0.0137747 +0.0114251 0.0275734 0.00440942 +0.00337666 -0.0559724 0.0148659 +-0.0262911 0.0586227 0.0207785 +-0.0699467 0.0813567 0.0499003 +0.0494602 -0.0133111 0.00757754 +0.00758285 0.0333008 0.0104911 +0.00657287 0.032122 0.00603963 +0.000332803 -0.0511328 0.0180756 +-0.021764 0.0620607 0.0118108 +-0.0454672 0.075167 0.035911 +0.00139884 0.045926 0.0128133 +0.0176314 0.0311493 0.00370344 +-0.0159418 -0.0158578 0.00793814 +-0.0229387 0.06916410000000001 0.0166572 +-0.00133409 -0.0449329 0.0187829 +-0.0538019 0.0611146 0.00198764 +0.0305208 -0.00256491 0.0101919 +0.0623596 -0.00697151 0.00683979 +0.0236819 -0.00777996 0.0526871 +0.0118138 -0.0144241 0.0430193 +0.0137156 -0.00365078 0.00732253 +-0.0257884 0.0686739 0.0150694 +-0.0530331 0.060812 0.00248197 +-0.000421194 -0.0523335 0.008791770000000001 +0.0193846 -0.00072024 0.0649221 +0.00485856 0.0133946 0.0114741 +-0.0053823 -0.0743714 0.0141262 +0.016958 0.0166471 0.00740593 +0.0429338 -0.0266961 0.0110582 +-0.06504749999999999 0.05473 0.00191127 +0.00924818 0.0356698 0.00715588 +-0.042468 0.0652669 0.00790867 +0.00699205 0.0348997 0.00576165 +-0.012123 0.00171435 0.00688121 +0.017741 0.00126373 0.0717161 +-0.00477874 -0.0228765 0.0123522 +-0.05496 0.0793832 0.0329037 +-0.0253736 -0.000654191 0.00342534 +0.0220159 -0.0128389 0.0555838 +0.0187915 0.00366305 0.06539010000000001 +-0.0635923 0.0794618 0.0351284 +0.0187293 0.00901455 0.0689246 +-0.0507436 0.0790633 0.0364811 +0.00440962 0.0291856 0.00589534 +-0.0610541 0.08157639999999999 0.0467801 +-0.0264169 0.06418980000000001 0.0180225 +0.0590681 -0.0129818 0.009692930000000001 +0.0316732 -0.013669 0.008927310000000001 +-0.0368828 0.0732351 0.028231 +0.0147007 -0.0293577 0.0425282 +-0.00226105 0.042112 0.008184220000000001 +-0.022404 0.068624 0.0211714 +0.018834 0.0296379 0.0101126 +0.0545664 -0.023882 0.00596013 +-0.0610274 0.0626039 0.00623226 +0.0209345 -0.0123916 0.0558755 +-0.064258 0.0639612 0.00701622 +-0.0530259 0.07099660000000001 0.0104874 +-0.000350232 0.0328643 0.009503569999999999 +0.0179821 0.0260225 0.00525665 +-0.071629 0.0809096 0.0500374 +0.0431333 -0.00662611 0.0109755 +-0.0367738 0.072104 0.0272887 +-0.00147996 0.0424733 0.00778004 +-0.0489442 0.0792518 0.0424775 +0.0178184 0.008309230000000001 0.0698262 +-0.00256208 -0.0518644 0.0119693 +-0.0024457 0.0347988 0.0115191 +-0.0226391 0.067054 0.0236986 +-0.0250562 0.070839 0.0181046 +0.0157661 -0.010775 0.0444953 +-0.0587069 0.0610686 0.00549325 +-0.0561989 0.0607157 0.00436391 +0.0028322 0.0311045 0.0076099 +-0.061857 0.079748 0.0514834 +-0.0580072 0.07448539999999999 0.0170926 +0.017366 0.0281829 0.00449304 +0.0175246 0.0303053 0.00632184 +-0.0583716 0.0812348 0.0494755 +-0.06276379999999999 0.08110589999999999 0.0418948 +0.009583370000000001 0.0391723 0.00889538 +0.0164997 0.0327763 0.00400793 +-0.0100537 -0.019407 0.0104569 +0.0535082 -0.023589 0.00757618 +-0.0184567 0.0672393 0.0165986 +-0.0660887 0.06395149999999999 0.00557639 +-0.008500499999999999 0.0591911 0.0132991 +0.0527123 -0.00658592 0.00801901 +0.00664445 0.0147496 0.00979726 +-0.0323364 0.06468409999999999 0.013176 +-0.06849810000000001 0.0817682 0.0541475 +0.0424951 -0.00680449 0.0104665 +-0.01583 0.06382989999999999 0.0140017 +-0.0408586 0.07478079999999999 0.0276312 +-0.0213675 0.00505684 0.00440033 +-0.0609542 0.0784149 0.029815 +0.0458286 -0.0196104 0.0115924 +0.0619857 -0.0044448 0.00717137 +-0.0549453 0.0736446 0.0144159 +-0.0660739 0.0797747 0.0511232 +-0.0150243 -0.0138696 0.00597473 +-0.0208919 0.06642729999999999 0.014553 +-0.0583912 0.07667309999999999 0.0277458 +-0.00499489 -0.0492059 0.0154875 +-0.0177596 -0.0149926 0.00640227 +-0.0656257 0.0638276 0.00437301 +-0.00111824 -0.0505712 0.010634 +-0.0234714 0.0595273 0.0150887 +-0.0117477 -0.00786715 0.0107629 +-0.0329423 0.0662408 0.012525 +-0.0588644 0.0778049 0.0265316 +-0.038272 0.07101209999999999 0.0277124 +0.0147178 0.0228905 0.00513556 +-0.00242697 -0.0228032 0.0106496 +-0.00998317 -0.0196685 0.00798312 +0.00194711 0.0338412 0.00734265 +-0.0101071 0.0571173 0.0108272 +-0.000192036 0.0305177 0.010316 +-0.06622359999999999 0.0609953 0.00234663 +-0.0383437 0.071981 0.0290737 +0.0464353 -0.0271448 0.00729223 +-0.0113654 0.0558876 0.00985606 +-0.0600686 0.0581853 0.00037707 +0.0184892 0.00651809 0.072001 +-0.0272353 0.0661385 0.0125002 +0.0386787 -0.009397559999999999 0.0110365 +-0.00702298 -0.0554164 0.0301677 +-0.0387296 0.0725599 0.0291973 +-0.0195884 -0.009713039999999999 0.00731553 +0.0009803979999999999 0.0340005 0.008311529999999999 +-0.00251349 -0.0493306 0.0137872 +-0.0208118 0.00468072 0.00662791 +0.0145465 0.0247675 0.00685396 +0.0539643 -0.00601143 0.00911787 +0.0615879 -0.00432066 0.00875869 +-0.0649217 0.0800024 0.0383643 +0.00460493 0.008497380000000001 0.0127005 +-0.0606311 0.0803611 0.0379233 +-0.00316884 0.0400824 0.00969248 +-0.0308482 0.067467 0.0126012 +0.0120049 0.00511369 0.00824306 +0.0117314 0.0134932 0.00784586 +0.0067401 0.0222359 0.00786688 +0.000365941 0.0444987 0.0334101 +0.00589042 0.0427357 0.0325284 +0.0134556 0.013691 0.0071386 +0.0155774 0.00572549 0.00675779 +-0.0442054 0.0654197 0.00607699 +0.00863004 0.0184766 0.00878081 +-0.0111016 -0.0170398 0.0107756 +-0.0162643 0.06208 0.0123266 +-0.06706429999999999 0.0628756 0.0047451 +-0.0673064 0.07917689999999999 0.0489333 +-0.0566743 0.0588231 0.00264455 +-0.07138410000000001 0.080001 0.0523997 +-0.0690781 0.0794039 0.0521145 +-0.0589744 0.07029879999999999 0.0123753 +-0.0108026 0.05228 0.00636676 +-0.0113486 0.0541547 0.00728553 +-0.0299136 0.06862409999999999 0.0165753 +0.0505332 -0.0225927 0.00635398 +0.0180077 0.0031318 0.07043870000000001 +-0.0235313 0.0640143 0.012641 +-0.0235569 0.00584404 0.00381922 +0.0384718 -0.0113423 0.0144484 +0.0182407 0.00232532 0.0728388 +-0.0235752 0.00407866 0.00373027 +-0.011585 0.0522432 0.00647843 +0.0400312 -0.00904366 0.0126741 +-0.0178591 -0.000359808 0.00797485 +-0.067167 0.06255139999999999 0.00392853 +-0.0596438 0.0779391 0.0290601 +0.0013543 0.0302152 0.00901705 +0.0168301 0.00522322 0.0737244 +0.0174324 0.00448014 0.0738384 +-0.0618546 0.0649931 0.00590465 +0.0194429 0.0304209 0.00452872 +-0.0236633 0.0648084 0.0124456 +-0.00249493 -0.0562542 0.012985 +-0.0025263 -0.0246783 0.0125409 +-0.0396392 0.0718092 0.02876 +-0.0158083 -0.0164708 0.00645267 +0.016879 0.0245859 0.0055459 +-0.06884990000000001 0.0811361 0.0461884 +0.0290982 -0.00647478 0.008279069999999999 +-0.041817 0.0761358 0.0343691 +-0.0642688 0.0653922 0.00517065 +-0.0162175 0.00239503 0.00694561 +0.00467524 0.0360758 0.00643588 +-0.0222973 0.0035638 0.00646752 +-0.0708092 0.0801688 0.0482801 +-0.0549524 0.07870829999999999 0.0296023 +-0.06310540000000001 0.0672415 0.00811831 +-0.0155444 -0.0163359 0.0060847 +-0.0574097 0.07880470000000001 0.0473507 +-0.0558952 0.0591814 0.001764 +-0.0177409 0.0619627 0.0144786 +-0.00178349 -0.0487397 0.0125937 +-0.0111058 0.0522074 0.008299040000000001 +-0.0260139 0.00360897 0.00461987 +-0.0204566 0.00423454 0.00564674 +0.00612936 0.0370467 0.00680554 +0.010446 0.0313554 0.00705031 +-0.0569353 0.05965 0.00118235 +-0.0506685 0.0625792 0.00279292 +-0.0249761 0.00485573 0.00443819 +0.0172421 0.00725128 0.07382619999999999 +-0.0219613 0.06430039999999999 0.0138184 +-0.00260185 -0.0513557 0.0142694 +-0.0167422 0.00259292 0.00779623 +0.00214524 0.0341103 0.00650831 +-0.0236765 0.00572293 0.004305 +-0.0616879 0.0784644 0.0353636 +-0.0125522 0.0533024 0.00573952 +-0.00373263 -0.048886 0.014509 +-0.00253347 -0.0472982 0.0131992 +-0.0128746 -0.017623 0.00940414 +-5.43548e-05 0.0393803 0.00728201 +-0.0258702 0.00405717 0.00525282 +0.0183599 0.0265636 0.00640112 +0.0459896 -0.0257989 0.0100883 +-0.0295424 0.06805940000000001 0.0247957 +-0.0245383 0.0634107 0.0123732 +0.0066096 0.0377811 0.00691952 +-0.0450015 0.0646553 0.00575343 +-0.0622505 0.0661482 0.00839783 +-0.0256248 0.0608105 0.0161665 +0.017488 0.00853314 0.07209649999999999 +-0.0596734 0.07050969999999999 0.009924850000000001 +-0.06657979999999999 0.06286890000000001 0.00493615 +-0.0624322 0.0664941 0.0080812 +0.0436037 -0.00911409 0.009504510000000001 +-0.0258241 0.00183578 0.00455937 +-0.07027029999999999 0.07969130000000001 0.0546337 +-0.027947 0.06304949999999999 0.0231884 +-0.0601839 0.07046330000000001 0.0106076 +-0.019796 -0.0130118 0.0069497 +-0.0183149 0.06305479999999999 0.012418 +-0.0302535 0.0701272 0.02364 +-0.0574291 0.07908510000000001 0.0314511 +-0.0506885 0.0650762 0.00396145 +-0.021101 0.0616869 0.0137094 +-0.0331684 0.0670427 0.023997 +0.0134393 0.00644533 0.00718965 +-0.0111807 -0.0194906 0.00818236 +-0.0255718 0.00304117 0.00332801 +-0.0126697 -0.015488 0.00653208 +-0.0247074 0.00660999 0.00551935 +0.0173416 0.0031807 0.0727906 +0.0172416 0.0236783 0.00588169 +0.0190309 0.0293428 0.00437137 +0.016715 0.00646681 0.0747173 +-0.0362286 0.072292 0.023504 +-0.0193589 -0.00042516 0.00470745 +-0.0218861 0.06436310000000001 0.0125137 +-0.0102557 0.0512168 0.00711881 +0.0404202 -0.00631757 0.0116411 +0.0462272 -0.00679819 0.0101561 +-0.0259792 0.0656558 0.0150971 +0.0162732 0.0229634 0.00624384 +0.00353474 0.0364474 0.008433390000000001 +4.6368e-06 0.0388726 0.009730829999999999 +-0.0216501 0.0633078 0.012475 +-0.06535530000000001 0.0635995 0.0060088 +-0.0129397 0.0533345 0.00604151 +-0.00189413 -0.0244631 0.013557 +-0.0610974 0.0673557 0.00916116 +0.0169636 0.00823874 0.0726305 +-0.0262169 0.00566462 0.00486021 +-0.00105663 -0.050339 0.013034 +-0.0522352 0.0618469 0.00239028 +-0.06586110000000001 0.0623674 0.00600767 +-0.0308719 0.0671807 0.0240148 +-0.0271033 0.0631674 0.0232081 +0.000463176 0.0377435 0.00713404 +0.0197653 -0.0105149 0.0573133 +-0.0261272 0.00574879 0.00514751 +-0.0256133 0.00236555 0.00535812 +0.0395658 -0.00664927 0.0115095 +-0.0346515 0.0704144 0.0260764 +-0.0676857 0.0619198 0.00410476 +-0.0352382 0.07226829999999999 0.0261851 +-0.0489272 0.0632235 0.00329626 +-0.0514659 0.0617489 0.00295197 +-0.070483 0.0805389 0.0464472 +$EndNodes +$Elements +1 1654 1 1654 +3 0 4 1654 +1 26 15 543 25 +2 227 308 190 188 +4 331 305 504 150 +5 142 328 128 138 +6 490 439 18 571 +7 364 289 287 414 +8 296 336 304 298 +9 564 419 300 381 +10 398 569 373 591 +11 486 473 639 422 +12 338 89 566 489 +13 332 554 543 424 +14 80 67 71 302 +15 149 146 109 108 +16 98 90 375 342 +17 341 308 325 313 +18 147 314 126 116 +19 124 318 156 131 +20 245 322 206 308 +21 348 311 516 186 +22 135 150 319 151 +23 147 314 307 311 +24 464 588 301 528 +25 461 33 35 333 +26 196 192 373 314 +27 108 81 302 122 +28 366 258 227 357 +29 511 107 512 353 +30 146 170 354 172 +31 297 175 156 130 +32 130 297 175 308 +33 318 159 319 195 +34 154 123 122 342 +35 261 308 259 260 +36 132 142 128 318 +37 241 250 240 205 +38 226 227 248 324 +39 575 609 475 49 +40 375 91 123 90 +41 260 308 255 251 +42 517 612 63 482 +43 120 117 131 297 +44 318 131 297 156 +45 147 319 311 307 +46 131 120 297 130 +47 120 297 111 117 +48 308 174 206 360 +49 148 313 325 175 +50 148 313 175 174 +51 302 80 122 81 +52 107 353 511 110 +53 322 231 198 197 +54 61 58 564 57 +55 240 386 212 221 +56 121 297 143 117 +57 121 297 117 111 +58 307 235 314 182 +59 307 314 166 182 +60 417 308 175 316 +61 308 175 360 417 +62 601 9 458 1 +63 459 429 536 599 +64 211 242 206 308 +65 528 588 301 356 +66 316 297 308 175 +67 197 188 308 228 +68 231 308 228 197 +69 231 197 322 308 +70 188 197 308 361 +71 322 361 308 197 +72 259 308 256 255 +73 298 306 304 299 +74 302 342 146 122 +75 251 322 245 308 +76 298 306 299 236 +77 342 302 169 129 +78 157 319 331 150 +79 190 195 324 227 +80 146 342 354 154 +81 190 297 308 324 +82 236 254 306 299 +83 354 179 201 322 +84 308 297 188 361 +85 361 188 164 297 +86 195 165 190 318 +87 307 215 257 235 +88 194 235 215 307 +89 174 129 148 313 +90 169 313 129 174 +91 322 255 251 201 +92 366 265 308 258 +93 227 308 258 366 +94 258 308 249 265 +95 227 308 228 258 +96 448 192 373 196 +97 228 308 249 258 +98 296 298 514 336 +99 125 150 348 126 +100 125 160 348 150 +101 244 264 242 316 +102 264 316 244 271 +103 224 233 225 219 +104 107 353 163 199 +105 217 223 219 225 +106 308 174 313 206 +107 206 313 179 174 +108 241 230 212 233 +109 241 233 212 218 +110 267 278 312 273 +111 267 312 262 273 +112 206 179 322 245 +113 242 245 206 308 +114 144 319 159 157 +115 265 308 266 272 +116 218 219 392 233 +117 264 324 316 271 +118 324 308 264 316 +119 297 318 117 131 +120 128 117 318 124 +121 354 207 201 177 +122 207 177 354 184 +123 155 163 353 203 +124 131 297 156 130 +125 395 330 236 202 +126 164 142 318 190 +127 253 314 234 311 +128 307 314 147 166 +129 331 234 253 254 +130 306 236 298 331 +131 156 297 316 175 +132 324 319 318 316 +133 297 324 316 308 +134 373 314 102 125 +135 167 155 378 192 +136 278 324 272 269 +137 278 276 272 324 +138 319 159 157 336 +139 267 257 312 243 +140 307 215 243 257 +141 156 297 318 316 +142 207 354 170 184 +143 124 144 139 156 +144 267 312 250 243 +145 144 151 139 319 +146 318 316 319 144 +147 316 139 319 144 +148 139 144 316 156 +149 316 191 312 319 +150 316 191 317 156 +151 313 308 175 174 +152 253 234 331 311 +153 331 395 234 236 +154 272 265 308 366 +155 103 140 133 510 +156 235 199 246 314 +157 246 237 314 199 +158 144 151 319 157 +159 92 157 151 144 +160 92 159 157 144 +161 395 234 236 330 +162 395 330 202 348 +163 348 330 202 209 +164 324 312 316 271 +165 266 308 324 272 +166 324 366 308 227 +167 242 264 245 308 +168 272 266 269 324 +169 135 151 319 139 +170 40 35 28 29 +171 88 148 129 342 +172 325 342 148 88 +173 314 116 147 166 +174 77 353 320 94 +175 331 262 319 306 +176 319 317 139 316 +177 450 329 482 328 +178 183 307 147 166 +179 188 361 176 197 +180 169 179 313 174 +181 314 196 348 373 +182 102 84 116 353 +183 102 77 84 353 +184 191 147 319 317 +185 307 262 257 312 +186 307 257 246 235 +187 307 257 262 246 +188 128 318 144 124 +189 246 314 237 253 +190 314 203 237 234 +191 142 128 318 138 +192 253 237 234 314 +193 306 319 331 336 +194 307 314 235 246 +195 316 250 312 191 +196 450 403 349 329 +197 121 297 101 143 +198 382 164 101 297 +199 369 198 322 193 +200 264 266 324 269 +201 322 354 170 207 +202 322 170 193 207 +203 353 84 116 110 +204 70 302 68 83 +205 331 311 234 395 +206 323 493 282 301 +207 269 278 324 271 +208 278 312 324 271 +209 207 170 180 184 +210 207 170 193 180 +211 325 130 175 308 +212 146 354 170 154 +213 354 302 342 146 +214 161 348 510 181 +215 182 314 199 235 +216 322 354 369 170 +217 231 207 322 198 +218 313 322 375 341 +219 375 361 341 322 +220 322 207 193 198 +221 297 143 164 101 +222 221 213 240 232 +223 190 188 308 297 +224 341 361 375 382 +225 341 308 313 322 +226 134 158 184 354 +227 247 308 261 249 +228 263 308 260 251 +229 318 319 159 144 +230 309 262 306 319 +231 250 204 243 312 +232 448 192 167 378 +233 37 333 620 35 +234 37 33 333 35 +235 297 318 316 324 +236 167 448 378 153 +237 212 218 233 219 +238 88 325 342 494 +239 246 307 314 253 +240 307 253 246 262 +241 126 311 150 348 +242 388 611 336 514 +243 348 234 420 314 +244 236 254 331 306 +245 348 314 311 234 +246 211 308 360 417 +247 373 102 320 125 +248 316 250 191 438 +249 250 205 191 438 +250 254 262 306 309 +251 254 309 306 310 +252 299 254 306 310 +253 331 262 306 254 +254 292 294 295 293 +255 194 307 215 204 +256 304 306 384 299 +257 267 312 257 262 +258 353 192 378 155 +259 319 159 336 195 +260 353 192 373 378 +261 336 185 388 195 +262 312 250 271 267 +263 271 250 312 316 +264 261 249 308 265 +265 268 308 265 261 +266 247 308 249 228 +267 227 195 324 226 +268 366 324 415 337 +269 337 366 324 357 +270 190 195 318 324 +271 156 318 124 144 +272 263 266 308 264 +273 251 263 308 264 +274 197 198 322 369 +275 154 354 369 342 +276 188 308 228 227 +277 79 328 138 92 +278 316 317 139 156 +279 360 175 308 174 +280 255 251 308 322 +281 255 256 252 308 +282 247 228 231 308 +283 247 308 231 256 +284 134 149 394 354 +285 83 162 96 302 +286 161 373 140 348 +287 88 67 302 68 +288 302 97 88 68 +289 512 166 314 182 +290 420 192 314 234 +291 348 330 420 234 +292 192 314 234 203 +293 91 123 105 115 +294 394 70 302 81 +295 309 273 262 319 +296 319 262 312 273 +297 67 302 68 70 +298 271 278 312 267 +299 66 57 326 58 +300 188 136 176 361 +301 157 331 185 504 +302 136 361 188 164 +303 244 250 271 316 +304 71 302 67 70 +305 244 213 232 240 +306 81 302 71 70 +307 354 149 108 146 +308 314 237 203 199 +309 506 378 435 629 +310 244 438 316 213 +311 97 302 169 162 +312 244 316 438 250 +313 313 129 342 169 +314 382 113 101 164 +315 506 435 378 94 +316 91 123 85 105 +317 308 264 245 251 +318 242 264 308 316 +319 450 349 482 329 +320 314 373 348 125 +321 92 138 159 144 +322 395 311 234 348 +323 278 273 324 312 +324 373 378 435 320 +325 147 311 319 135 +326 126 311 135 150 +327 126 135 311 147 +328 314 348 311 126 +329 83 302 82 70 +330 378 435 629 373 +331 195 159 165 318 +332 316 312 324 319 +333 156 175 316 387 +334 336 298 514 331 +335 88 342 129 302 +336 319 307 331 311 +337 253 314 311 307 +338 311 331 253 307 +339 297 341 308 130 +340 314 348 126 125 +341 147 314 311 126 +342 61 339 99 338 +343 250 204 312 191 +344 305 185 508 331 +345 211 242 308 316 +346 211 308 417 316 +347 213 316 211 417 +348 214 215 230 204 +349 244 316 242 211 +350 244 211 213 316 +351 465 501 344 502 +352 108 354 302 394 +353 313 129 148 342 +354 337 324 415 248 +355 337 258 366 357 +356 121 101 297 111 +357 382 101 111 297 +358 157 159 185 336 +359 226 336 195 324 +360 307 262 331 253 +361 307 262 319 331 +362 331 254 253 262 +363 248 336 552 296 +364 319 324 195 336 +365 248 296 226 336 +366 324 248 336 552 +367 147 183 191 307 +368 282 281 276 323 +369 281 323 282 301 +370 109 119 105 122 +371 297 143 117 318 +372 109 122 105 80 +373 308 366 324 272 +374 297 318 324 190 +375 297 190 164 318 +376 214 204 230 212 +377 224 212 214 230 +378 297 143 318 164 +379 264 308 324 266 +380 264 269 324 271 +381 132 117 143 318 +382 130 297 341 120 +383 341 130 120 98 +384 277 343 356 279 +385 325 308 175 313 +386 109 81 108 122 +387 109 122 108 146 +388 348 234 395 330 +389 341 111 120 297 +390 341 100 98 120 +391 341 111 100 120 +392 226 336 324 248 +393 318 319 324 195 +394 275 270 324 309 +395 309 336 324 319 +396 552 270 336 324 +397 273 309 275 324 +398 403 328 329 450 +399 382 111 341 297 +400 361 322 308 341 +401 361 341 308 297 +402 342 85 73 90 +403 342 73 85 80 +404 323 324 366 276 +405 361 297 164 382 +406 96 82 83 302 +407 45 647 44 42 +408 179 354 201 177 +409 53 621 54 347 +410 117 124 131 318 +411 156 144 316 318 +412 369 198 193 141 +413 342 302 88 67 +414 67 80 342 302 +415 73 80 342 67 +416 342 73 67 76 +417 372 528 289 285 +418 285 528 289 287 +419 355 98 325 494 +420 122 119 105 123 +421 394 82 134 302 +422 494 88 76 342 +423 109 81 122 80 +424 447 580 503 505 +425 114 118 141 145 +426 311 150 319 135 +427 108 122 302 146 +428 204 307 183 194 +429 191 204 307 183 +430 382 101 100 111 +431 382 111 100 341 +432 318 159 138 144 +433 588 281 301 356 +434 87 61 77 57 +435 318 159 165 138 +436 7 12 2 486 +437 316 191 319 317 +438 208 196 449 445 +439 322 369 354 313 +440 354 158 177 162 +441 354 169 162 179 +442 313 369 354 342 +443 179 162 354 177 +444 130 98 341 355 +445 325 130 341 355 +446 337 357 324 248 +447 324 357 227 248 +448 588 281 464 301 +449 375 341 382 98 +450 454 75 61 155 +451 353 77 84 74 +452 331 305 185 504 +453 311 331 319 150 +454 378 339 167 106 +455 318 190 142 165 +456 138 142 165 318 +457 18 12 397 14 +458 298 514 331 513 +459 118 137 141 168 +460 298 331 236 395 +461 395 298 331 513 +462 93 157 92 159 +463 354 158 184 177 +464 151 157 92 93 +465 78 93 151 92 +466 378 448 629 153 +467 102 314 126 125 +468 126 116 314 102 +469 61 72 303 75 +470 39 461 350 553 +471 350 39 33 461 +472 311 331 513 395 +473 311 331 305 509 +474 353 102 314 116 +475 204 215 243 307 +476 106 153 167 378 +477 97 162 83 302 +478 107 353 199 512 +479 297 188 164 190 +480 147 319 139 135 +481 77 353 87 74 +482 353 203 199 314 +483 512 314 353 199 +484 37 38 29 35 +485 485 140 373 125 +486 398 448 373 196 +487 196 570 373 398 +488 324 248 552 415 +489 415 270 552 324 +490 52 57 594 564 +491 285 289 414 287 +492 438 250 205 240 +493 524 425 25 17 +494 29 25 524 425 +495 87 77 61 353 +496 93 92 138 159 +497 93 92 79 138 +498 203 192 353 155 +499 192 353 314 203 +500 88 302 129 97 +501 169 342 354 302 +502 147 319 317 139 +503 435 426 629 373 +504 197 168 369 176 +505 369 176 361 197 +506 157 151 319 150 +507 307 319 312 191 +508 312 307 191 204 +509 628 373 441 374 +510 513 331 311 509 +511 49 594 413 46 +512 303 163 87 61 +513 146 342 154 122 +514 274 366 415 337 +515 274 258 366 337 +516 87 57 74 66 +517 304 306 336 384 +518 204 250 205 191 +519 110 74 66 87 +520 163 87 61 353 +521 204 205 250 241 +522 387 438 213 316 +523 150 160 348 311 +524 313 369 342 375 +525 313 322 369 375 +526 97 129 169 302 +527 504 305 393 150 +528 181 348 500 187 +529 610 527 42 44 +530 44 527 42 620 +531 311 305 456 509 +532 311 509 456 516 +533 365 512 166 116 +534 116 512 166 314 +535 509 305 508 331 +536 322 369 193 170 +537 535 526 581 632 +538 182 314 512 199 +539 497 441 373 540 +540 37 42 46 527 +541 500 209 187 348 +542 312 257 307 243 +543 323 366 281 276 +544 348 420 209 196 +545 366 279 276 272 +546 202 500 186 348 +547 386 406 221 232 +548 64 526 62 489 +549 336 159 185 195 +550 404 24 559 335 +551 404 24 607 559 +552 384 336 552 270 +553 244 240 438 213 +554 244 438 240 250 +555 430 461 620 333 +556 461 333 35 620 +557 61 564 64 334 +558 381 437 47 413 +559 279 277 265 258 +560 279 277 258 274 +561 186 500 181 348 +562 140 510 348 160 +563 377 410 36 350 +564 202 330 236 209 +565 380 345 614 468 +566 99 339 378 106 +567 378 106 418 99 +568 378 448 373 629 +569 194 235 307 182 +570 194 307 166 182 +571 194 307 183 166 +572 353 373 320 378 +573 68 97 83 302 +574 347 496 604 476 +575 161 181 411 373 +576 570 374 400 368 +577 40 38 35 29 +578 364 289 327 528 +579 324 309 319 273 +580 353 378 320 94 +581 358 91 471 375 +582 134 394 302 354 +583 394 149 108 354 +584 172 354 146 149 +585 382 358 471 375 +586 101 382 90 358 +587 651 346 638 390 +588 382 90 100 101 +589 334 594 564 475 +590 369 361 375 322 +591 322 197 369 361 +592 342 325 98 494 +593 325 313 148 342 +594 342 325 375 98 +595 115 369 123 367 +596 342 98 76 494 +597 369 375 576 115 +598 353 512 116 314 +599 336 304 552 296 +600 336 306 304 298 +601 226 514 336 296 +602 108 302 81 394 +603 181 411 373 374 +604 26 440 571 383 +605 26 383 346 440 +606 211 360 308 206 +607 87 74 57 77 +608 358 113 101 382 +609 195 388 336 226 +610 241 233 218 238 +611 155 339 378 353 +612 345 79 468 476 +613 213 316 417 175 +614 387 316 213 175 +615 312 307 262 319 +616 435 485 426 373 +617 435 373 125 485 +618 299 310 306 384 +619 26 425 25 34 +620 118 114 367 434 +621 26 34 25 608 +622 223 222 529 392 +623 527 38 37 35 +624 37 527 46 38 +625 342 123 90 375 +626 342 123 85 90 +627 335 350 33 35 +628 350 461 33 35 +629 85 91 90 123 +630 259 247 308 261 +631 629 628 448 373 +632 633 142 328 128 +633 629 497 628 373 +634 303 61 87 72 +635 236 254 234 331 +636 341 98 325 355 +637 373 570 400 569 +638 398 570 373 569 +639 49 413 527 46 +640 49 46 527 457 +641 49 626 48 527 +642 241 204 243 250 +643 49 527 48 457 +644 392 218 233 238 +645 233 392 238 223 +646 178 198 197 141 +647 198 197 141 369 +648 364 290 287 528 +649 419 381 564 413 +650 92 78 79 59 +651 192 373 314 353 +652 386 406 238 423 +653 367 369 137 391 +654 437 413 419 606 +655 413 437 47 606 +656 239 252 322 255 +657 454 61 339 155 +658 34 466 425 29 +659 221 386 232 240 +660 60 64 489 484 +661 484 65 60 64 +662 212 386 218 221 +663 241 240 386 212 +664 241 205 240 212 +665 607 24 16 470 +666 620 42 37 527 +667 37 333 42 620 +668 95 87 66 69 +669 113 164 382 361 +670 410 30 432 21 +671 371 1 522 458 +672 527 47 43 40 +673 596 425 17 15 +674 393 456 160 311 +675 110 95 87 66 +676 160 311 456 516 +677 512 511 365 166 +678 353 511 365 512 +679 128 144 318 138 +680 341 130 325 308 +681 87 61 57 58 +682 419 58 564 72 +683 414 289 327 364 +684 320 378 435 94 +685 364 528 287 289 +686 212 221 205 240 +687 134 172 149 354 +688 134 172 354 184 +689 319 147 191 307 +690 589 641 606 436 +691 347 79 59 476 +692 345 79 476 92 +693 92 138 144 328 +694 86 92 144 328 +695 32 399 34 38 +696 306 309 336 310 +697 347 604 468 476 +698 347 468 79 476 +699 614 345 79 468 +700 384 310 336 270 +701 439 25 26 422 +702 196 192 314 420 +703 348 420 196 314 +704 132 143 142 318 +705 164 142 143 318 +706 386 406 423 221 +707 35 527 38 40 +708 158 354 96 162 +709 169 302 354 162 +710 334 475 564 363 +711 155 61 303 75 +712 94 353 378 339 +713 224 233 219 212 +714 214 215 204 194 +715 204 243 230 241 +716 204 230 212 241 +717 391 474 369 136 +718 286 588 528 356 +719 35 620 527 47 +720 136 474 361 565 +721 566 526 632 64 +722 490 439 11 14 +723 209 330 420 348 +724 35 527 40 47 +725 76 342 73 98 +726 77 353 102 320 +727 268 308 261 260 +728 167 155 339 378 +729 465 289 385 344 +730 255 308 260 259 +731 335 24 470 33 +732 559 24 470 335 +733 522 1 371 428 +734 347 53 496 54 +735 559 24 607 470 +736 476 347 496 54 +737 312 204 243 307 +738 230 215 243 204 +739 241 218 212 386 +740 241 238 218 386 +741 29 33 28 23 +742 23 335 559 470 +743 297 382 361 341 +744 336 611 185 331 +745 388 185 336 611 +746 353 373 102 320 +747 373 102 314 353 +748 44 527 606 610 +749 74 110 84 353 +750 610 527 606 413 +751 325 341 375 98 +752 369 136 137 391 +753 169 354 342 313 +754 274 366 279 281 +755 281 366 279 276 +756 322 313 206 308 +757 414 289 344 385 +758 114 546 367 434 +759 367 391 434 369 +760 155 163 303 61 +761 47 620 527 44 +762 384 304 552 336 +763 384 310 306 336 +764 99 378 339 94 +765 506 94 378 99 +766 365 353 512 116 +767 378 99 418 506 +768 478 23 559 470 +769 328 86 633 128 +770 265 308 268 266 +771 268 308 263 266 +772 564 419 436 58 +773 460 75 564 65 +774 339 61 99 94 +775 518 564 65 460 +776 643 216 229 392 +777 342 88 76 67 +778 26 422 11 439 +779 26 440 439 571 +780 411 161 373 441 +781 442 467 412 10 +782 350 377 24 33 +783 225 409 217 223 +784 410 377 24 350 +785 24 350 33 335 +786 371 522 523 458 +787 278 324 273 276 +788 273 324 275 276 +789 170 354 172 184 +790 169 179 354 313 +791 607 16 24 580 +792 367 391 137 118 +793 35 620 37 527 +794 548 33 461 333 +795 414 385 344 294 +796 414 289 288 344 +797 65 64 484 454 +798 93 79 78 401 +799 375 382 358 90 +800 413 575 564 594 +801 187 181 368 189 +802 358 375 90 91 +803 275 276 324 323 +804 493 270 323 275 +805 532 323 276 275 +806 324 270 323 415 +807 275 323 324 270 +808 157 331 319 336 +809 454 339 61 338 +810 527 47 507 43 +811 74 87 110 353 +812 61 353 339 155 +813 444 445 618 379 +814 173 133 160 510 +815 352 604 468 347 +816 161 181 373 348 +817 23 335 470 33 +818 181 187 374 373 +819 29 35 28 33 +820 348 187 181 373 +821 562 10 412 447 +822 10 580 503 447 +823 399 351 34 38 +824 515 592 399 32 +825 434 112 637 474 +826 134 82 96 302 +827 224 230 233 212 +828 134 302 96 354 +829 302 354 162 96 +830 376 64 60 564 +831 606 640 589 45 +832 369 137 168 141 +833 113 361 583 136 +834 197 369 168 141 +835 12 7 4 14 +836 510 181 173 171 +837 61 339 353 94 +838 369 154 170 354 +839 404 607 24 21 +840 411 374 578 441 +841 500 186 189 480 +842 535 526 632 566 +843 628 441 497 483 +844 478 23 28 559 +845 28 335 559 23 +846 93 92 78 79 +847 554 473 631 453 +848 198 178 193 141 +849 187 444 209 500 +850 226 388 336 514 +851 287 464 285 528 +852 528 301 285 372 +853 497 629 426 373 +854 394 302 70 82 +855 64 61 454 75 +856 444 587 618 445 +857 467 458 371 523 +858 371 523 520 467 +859 371 520 551 467 +860 385 465 294 292 +861 468 604 345 476 +862 584 517 63 345 +863 176 136 137 369 +864 439 440 18 571 +865 490 26 11 439 +866 324 366 227 357 +867 606 413 419 436 +868 527 48 477 507 +869 527 477 48 457 +870 527 492 48 507 +871 527 626 48 492 +872 134 354 96 158 +873 62 64 489 60 +874 52 57 370 594 +875 326 52 55 564 +876 524 425 17 19 +877 373 441 161 540 +878 373 161 140 540 +879 66 326 55 58 +880 58 326 55 564 +881 310 309 336 270 +882 324 270 336 309 +883 157 336 185 331 +884 181 411 171 161 +885 640 589 641 606 +886 537 557 621 54 +887 282 285 340 288 +888 372 285 288 340 +889 382 100 98 341 +890 502 294 465 292 +891 43 34 351 38 +892 221 240 213 205 +893 438 240 205 213 +894 425 466 524 29 +895 354 302 146 108 +896 435 426 506 629 +897 497 506 426 629 +898 187 181 374 368 +899 517 79 614 345 +900 342 90 73 98 +901 180 141 178 152 +902 178 152 141 168 +903 193 180 141 178 +904 140 161 348 510 +905 9 442 13 362 +906 442 9 13 467 +907 408 505 503 580 +908 607 580 408 16 +909 327 289 414 385 +910 372 284 283 340 +911 359 89 526 566 +912 607 539 478 470 +913 140 373 125 348 +914 328 86 92 517 +915 527 47 44 606 +916 155 163 61 353 +917 367 391 118 434 +918 338 64 61 454 +919 64 338 484 454 +920 359 89 566 338 +921 489 526 566 64 +922 448 192 378 373 +923 350 39 377 33 +924 369 137 176 168 +925 377 350 553 39 +926 325 313 375 341 +927 340 288 625 282 +928 342 313 375 325 +929 524 466 19 20 +930 425 466 19 524 +931 348 395 186 202 +932 610 44 42 45 +933 409 433 217 223 +934 217 433 529 223 +935 582 375 471 115 +936 434 474 637 369 +937 382 375 471 582 +938 98 90 382 375 +939 382 100 90 98 +940 123 105 122 85 +941 122 85 105 80 +942 43 40 34 38 +943 369 474 361 136 +944 469 452 564 460 +945 46 41 527 457 +946 415 366 274 323 +947 191 387 316 438 +948 191 387 156 316 +949 434 391 474 369 +950 502 294 344 465 +951 502 294 292 293 +952 476 59 92 79 +953 306 309 319 336 +954 528 301 464 285 +955 301 282 464 285 +956 208 449 210 379 +957 210 379 220 208 +958 551 520 10 467 +959 359 89 339 106 +960 110 353 365 116 +961 353 511 110 365 +962 118 141 145 152 +963 34 28 466 29 +964 621 347 59 54 +965 59 621 79 347 +966 342 80 122 302 +967 369 123 154 342 +968 123 85 122 342 +969 122 342 85 80 +970 450 349 612 482 +971 564 55 436 413 +972 40 38 29 34 +973 606 641 413 436 +974 28 35 335 33 +975 34 25 32 29 +976 487 548 495 479 +977 187 209 196 348 +978 461 479 430 495 +979 311 513 509 186 +980 395 311 348 186 +981 187 196 209 444 +982 485 540 426 373 +983 21 580 24 447 +984 412 447 21 562 +985 412 562 21 446 +986 447 580 24 10 +987 46 527 610 413 +988 229 392 216 222 +989 323 281 366 274 +990 281 301 274 323 +991 599 625 429 282 +992 608 25 32 34 +993 372 288 284 340 +994 227 324 190 308 +995 373 196 348 187 +996 425 25 34 29 +997 628 448 373 591 +998 591 448 373 398 +999 477 43 41 527 +1000 80 71 81 302 +1001 457 477 41 527 +1002 647 487 430 479 +1003 628 373 497 441 +1004 578 628 441 374 +1005 410 24 335 350 +1006 393 311 160 150 +1007 367 118 137 141 +1008 343 488 356 396 +1009 87 72 61 58 +1010 488 588 356 396 +1011 476 54 59 347 +1012 94 353 61 77 +1013 110 353 87 107 +1014 251 245 322 201 +1015 245 179 322 201 +1016 11 422 486 14 +1017 287 588 464 528 +1018 10 467 412 551 +1019 13 551 412 467 +1020 371 467 551 13 +1021 551 10 8 412 +1022 113 164 361 136 +1023 425 25 15 26 +1024 140 348 125 160 +1025 451 588 528 286 +1026 180 152 145 141 +1027 607 16 539 470 +1028 374 570 400 373 +1029 373 374 556 400 +1030 374 373 556 628 +1031 441 628 578 483 +1032 497 642 418 629 +1033 167 89 106 339 +1034 346 440 390 521 +1035 369 123 342 375 +1036 583 382 498 361 +1037 564 75 72 61 +1038 564 61 64 75 +1039 345 517 79 92 +1040 533 529 223 222 +1041 498 582 576 375 +1042 575 376 609 49 +1043 412 10 8 447 +1044 561 472 549 468 +1045 239 322 252 231 +1046 397 12 4 14 +1047 367 369 434 576 +1048 206 313 322 179 +1049 322 179 313 354 +1050 12 2 4 7 +1051 346 638 26 608 +1052 66 87 57 58 +1053 72 58 564 61 +1054 322 207 231 239 +1055 201 354 322 207 +1056 239 255 322 201 +1057 533 402 529 222 +1058 60 518 564 65 +1059 11 486 12 14 +1060 118 168 141 152 +1061 60 376 564 518 +1062 576 375 582 115 +1063 515 34 399 351 +1064 334 564 64 363 +1065 311 331 150 305 +1066 473 538 597 519 +1067 564 594 575 475 +1068 36 30 432 410 +1069 343 396 356 279 +1070 281 279 356 396 +1071 281 274 301 356 +1072 486 7 14 422 +1073 642 153 585 629 +1074 153 642 628 629 +1075 503 447 8 10 +1076 461 430 620 416 +1077 493 270 275 280 +1078 275 493 532 323 +1079 532 493 282 323 +1080 461 495 430 416 +1081 493 532 280 275 +1082 389 381 47 413 +1083 49 413 626 527 +1084 500 189 186 181 +1085 498 382 582 375 +1086 410 30 24 377 +1087 30 410 36 377 +1088 366 265 279 272 +1089 608 34 32 31 +1090 527 40 43 38 +1091 46 527 41 38 +1092 43 527 38 41 +1093 597 639 7 486 +1094 306 298 336 331 +1095 11 26 15 543 +1096 554 11 15 543 +1097 416 430 620 649 +1098 291 290 364 327 +1099 637 498 375 361 +1100 39 548 33 461 +1101 422 634 25 543 +1102 583 582 382 113 +1103 367 114 118 141 +1104 473 422 11 554 +1105 178 197 168 141 +1106 375 369 123 115 +1107 91 123 115 375 +1108 377 350 36 553 +1109 173 181 516 186 +1110 110 95 107 87 +1111 353 107 163 87 +1112 46 527 42 610 +1113 500 209 348 202 +1114 334 61 564 57 +1115 510 103 140 161 +1116 160 104 140 133 +1117 486 11 473 422 +1118 336 611 331 514 +1119 576 434 637 369 +1120 29 466 524 20 +1121 366 279 265 258 +1122 366 279 258 274 +1123 89 484 338 454 +1124 462 621 568 534 +1125 133 104 140 103 +1126 462 534 568 531 +1127 521 440 390 563 +1128 383 440 563 390 +1129 141 154 170 369 +1130 141 193 369 170 +1131 173 181 510 516 +1132 348 510 181 516 +1133 324 366 276 272 +1134 415 324 366 323 +1135 477 527 507 43 +1136 26 25 440 346 +1137 430 333 42 479 +1138 460 452 564 75 +1139 31 515 32 592 +1140 181 189 187 500 +1141 389 527 413 47 +1142 413 389 626 527 +1143 376 590 49 575 +1144 331 611 185 508 +1145 223 392 407 219 +1146 223 233 392 219 +1147 538 648 597 519 +1148 597 648 538 486 +1149 557 537 568 499 +1150 553 39 461 416 +1151 290 528 451 287 +1152 554 453 332 560 +1153 601 467 458 9 +1154 623 525 535 566 +1155 566 525 535 526 +1156 378 106 431 418 +1157 53 496 352 347 +1158 564 300 419 72 +1159 564 452 300 72 +1160 2 6 7 486 +1161 421 451 528 286 +1162 451 528 588 287 +1163 409 595 433 491 +1164 79 621 78 401 +1165 401 621 78 555 +1166 78 537 555 621 +1167 599 340 282 301 +1168 493 599 282 301 +1169 430 620 42 333 +1170 565 498 112 637 +1171 583 498 112 565 +1172 599 429 536 282 +1173 599 625 459 429 +1174 543 554 332 15 +1175 474 112 637 565 +1176 364 290 528 327 +1177 548 461 479 333 +1178 461 333 430 479 +1179 383 390 346 440 +1180 65 60 64 564 +1181 65 64 75 564 +1182 383 638 346 390 +1183 380 468 614 549 +1184 532 282 276 323 +1185 157 331 504 150 +1186 89 454 338 339 +1187 167 454 89 339 +1188 8 5 10 551 +1189 5 520 10 551 +1190 492 626 545 389 +1191 389 626 545 469 +1192 37 33 35 29 +1193 615 568 499 557 +1194 500 186 480 202 +1195 54 56 53 496 +1196 294 295 291 385 +1197 295 291 385 327 +1198 295 294 292 385 +1199 474 637 361 565 +1200 497 373 426 540 +1201 40 29 28 34 +1202 535 525 581 526 +1203 328 92 79 517 +1204 496 56 352 604 +1205 459 536 646 493 +1206 459 429 624 536 +1207 493 536 280 532 +1208 25 346 26 608 +1209 351 399 41 38 +1210 43 41 38 351 +1211 527 413 47 606 +1212 308 252 322 231 +1213 308 255 322 252 +1214 256 231 252 308 +1215 256 308 259 247 +1216 21 30 24 410 +1217 21 30 562 24 +1218 315 621 555 568 +1219 217 219 223 407 +1220 225 223 219 233 +1221 407 217 529 223 +1222 381 452 300 564 +1223 595 635 433 491 +1224 414 385 291 327 +1225 416 39 461 495 +1226 461 39 548 495 +1227 461 548 479 495 +1228 301 282 281 464 +1229 301 282 285 340 +1230 315 621 568 462 +1231 372 289 288 285 +1232 289 288 285 414 +1233 431 153 106 378 +1234 55 641 589 436 +1235 651 572 638 608 +1236 564 452 72 75 +1237 573 534 567 613 +1238 567 645 600 534 +1239 499 568 577 537 +1240 414 327 291 364 +1241 561 549 614 468 +1242 338 489 566 64 +1243 89 484 489 338 +1244 385 294 465 344 +1245 445 196 444 209 +1246 209 550 444 427 +1247 490 14 11 12 +1248 490 18 14 12 +1249 597 648 486 7 +1250 486 639 7 422 +1251 639 473 597 631 +1252 529 491 616 533 +1253 435 320 125 373 +1254 616 491 529 541 +1255 497 628 642 629 +1256 46 52 413 602 +1257 623 359 566 338 +1258 497 506 629 418 +1259 99 359 623 338 +1260 65 64 454 75 +1261 209 617 550 427 +1262 86 328 144 128 +1263 570 187 374 368 +1264 403 86 633 328 +1265 601 522 458 523 +1266 604 352 472 56 +1267 273 312 319 324 +1268 380 614 63 549 +1269 561 549 63 614 +1270 623 525 566 359 +1271 359 525 566 526 +1272 566 89 526 489 +1273 113 382 358 471 +1274 582 471 382 113 +1275 523 467 458 601 +1276 268 308 260 263 +1277 374 628 556 578 +1278 498 582 382 583 +1279 586 645 534 557 +1280 361 176 369 136 +1281 277 356 274 279 +1282 576 637 375 369 +1283 637 375 369 361 +1284 373 556 569 400 +1285 556 373 569 628 +1286 447 562 24 21 +1287 47 492 527 507 +1288 495 39 548 487 +1289 572 608 651 650 +1290 541 619 542 574 +1291 27 562 21 30 +1292 21 446 562 27 +1293 517 328 614 79 +1294 545 530 622 575 +1295 522 371 523 558 +1296 523 371 520 558 +1297 471 91 115 375 +1298 578 127 628 556 +1299 127 153 628 556 +1300 641 413 55 52 +1301 55 564 436 58 +1302 564 334 57 594 +1303 55 641 436 413 +1304 575 413 49 594 +1305 15 17 596 560 +1306 521 440 563 571 +1307 632 581 62 526 +1308 285 372 301 340 +1309 290 451 528 421 +1310 326 57 564 58 +1311 205 212 241 204 +1312 564 452 469 381 +1313 239 322 207 201 +1314 223 392 529 407 +1315 381 564 413 469 +1316 395 513 311 186 +1317 389 469 413 626 +1318 136 361 583 565 +1319 586 645 567 534 +1320 32 25 608 346 +1321 369 367 137 141 +1322 469 575 545 622 +1323 593 543 634 422 +1324 373 569 628 591 +1325 556 569 153 628 +1326 196 187 373 570 +1327 167 454 339 155 +1328 590 626 575 530 +1329 536 493 282 532 +1330 133 140 160 510 +1331 376 363 64 564 +1332 209 427 444 587 +1333 571 440 563 383 +1334 498 375 576 637 +1335 531 534 568 579 +1336 534 568 557 621 +1337 218 392 643 238 +1338 568 555 577 537 +1339 475 609 363 49 +1340 363 609 475 564 +1341 393 311 150 305 +1342 19 425 17 596 +1343 596 17 603 560 +1344 522 428 371 558 +1345 127 628 497 483 +1346 492 48 545 626 +1347 21 607 24 580 +1348 132 117 318 128 +1349 633 132 547 142 +1350 437 381 419 413 +1351 419 381 437 300 +1352 173 181 186 171 +1353 405 613 600 534 +1354 632 526 62 64 +1355 489 484 64 338 +1356 600 54 53 621 +1357 29 20 28 466 +1358 20 28 466 443 +1359 49 48 626 590 +1360 63 345 614 380 +1361 584 345 63 380 +1362 470 607 559 478 +1363 28 23 22 20 +1364 478 23 22 28 +1365 473 422 554 631 +1366 555 537 568 621 +1367 18 490 14 439 +1368 596 17 19 603 +1369 571 440 18 521 +1370 542 491 616 541 +1371 534 568 615 557 +1372 534 568 579 615 +1373 392 222 229 238 +1374 626 48 530 590 +1375 238 406 229 423 +1376 629 585 642 418 +1377 418 506 629 378 +1378 378 431 629 418 +1379 153 448 628 591 +1380 591 569 628 153 +1381 550 209 500 627 +1382 515 31 32 34 +1383 209 627 550 617 +1384 569 556 153 400 +1385 645 621 557 54 +1386 529 491 533 223 +1387 601 1 458 522 +1388 522 601 1 3 +1389 359 339 99 106 +1390 338 99 359 339 +1391 49 575 626 413 +1392 473 597 631 453 +1393 605 564 518 460 +1394 222 392 402 529 +1395 113 382 583 361 +1396 33 335 28 23 +1397 370 52 594 46 +1398 408 505 580 607 +1399 413 640 602 641 +1400 630 376 564 609 +1401 49 376 609 363 +1402 363 376 609 564 +1403 393 456 311 305 +1404 218 221 386 643 +1405 643 386 423 221 +1406 141 123 369 367 +1407 498 382 375 361 +1408 474 637 369 361 +1409 558 371 520 551 +1410 558 428 371 551 +1411 374 441 411 373 +1412 422 25 26 543 +1413 25 17 15 634 +1414 606 44 610 45 +1415 367 115 369 576 +1416 367 576 546 115 +1417 636 573 567 613 +1418 615 51 579 573 +1419 50 51 615 636 +1420 55 413 564 52 +1421 594 52 413 46 +1422 564 326 52 57 +1423 367 434 546 576 +1424 208 449 379 445 +1425 379 445 544 208 +1426 26 439 440 25 +1427 622 575 605 469 +1428 636 586 567 573 +1429 573 586 567 534 +1430 599 625 340 283 +1431 605 630 518 564 +1432 171 510 181 161 +1433 32 29 38 34 +1434 402 216 392 222 +1435 223 222 392 238 +1436 389 492 527 47 +1437 389 492 626 527 +1438 577 555 78 537 +1439 315 621 401 555 +1440 15 598 634 560 +1441 634 17 15 560 +1442 481 142 328 633 +1443 128 328 144 138 +1444 413 610 640 606 +1445 640 606 610 45 +1446 379 449 444 445 +1447 187 449 196 444 +1448 445 449 444 196 +1449 605 564 460 469 +1450 575 564 605 469 +1451 541 200 619 574 +1452 564 436 419 413 +1453 517 482 63 614 +1454 154 369 141 123 +1455 583 498 565 361 +1456 498 361 637 565 +1457 622 530 630 575 +1458 21 30 432 27 +1459 173 510 160 516 +1460 311 160 348 516 +1461 485 140 540 373 +1462 21 505 580 447 +1463 490 26 439 571 +1464 379 544 220 208 +1465 348 516 181 186 +1466 186 509 311 516 +1467 209 202 627 617 +1468 433 635 529 491 +1469 430 42 620 44 +1470 649 430 620 44 +1471 529 635 541 491 +1472 404 24 410 21 +1473 404 410 24 335 +1474 89 338 359 339 +1475 450 328 482 517 +1476 517 328 482 614 +1477 78 59 537 621 +1478 588 396 281 356 +1479 286 488 588 356 +1480 424 543 593 422 +1481 463 607 408 16 +1482 389 381 413 469 +1483 413 469 575 626 +1484 626 469 575 545 +1485 554 11 543 422 +1486 459 624 646 536 +1487 332 543 593 424 +1488 631 554 424 422 +1489 153 431 629 378 +1490 545 48 530 626 +1491 626 530 545 575 +1492 59 621 78 79 +1493 160 510 348 516 +1494 626 590 575 49 +1495 576 434 112 637 +1496 498 576 112 637 +1497 346 651 638 608 +1498 13 442 412 362 +1499 13 467 412 442 +1500 132 142 633 128 +1501 184 180 172 170 +1502 631 332 424 554 +1503 531 573 579 51 +1504 521 571 563 18 +1505 599 625 282 340 +1506 622 630 605 575 +1507 562 442 362 412 +1508 193 180 170 141 +1509 50 644 636 615 +1510 443 466 20 19 +1511 616 542 533 491 +1512 413 594 564 52 +1513 621 53 600 405 +1514 362 562 446 27 +1515 403 547 321 481 +1516 403 481 321 329 +1517 562 442 412 10 +1518 493 459 536 599 +1519 493 599 536 282 +1520 450 86 328 517 +1521 413 602 610 46 +1522 29 23 28 20 +1523 223 409 433 491 +1524 621 59 537 54 +1525 13 362 412 446 +1526 439 422 11 14 +1527 639 473 631 422 +1528 450 612 584 517 +1529 450 482 612 517 +1530 413 641 602 52 +1531 447 10 24 562 +1532 531 573 534 579 +1533 380 345 468 604 +1534 587 427 444 618 +1535 613 567 600 534 +1536 218 386 238 643 +1537 643 238 423 386 +1538 347 496 352 604 +1539 63 345 517 614 +1540 584 612 63 517 +1541 629 431 585 418 +1542 153 431 585 629 +1543 463 539 478 607 +1544 463 539 607 16 +1545 564 609 475 575 +1546 533 529 402 616 +1547 376 630 564 518 +1548 645 54 600 621 +1549 380 468 472 604 +1550 604 468 472 352 +1551 380 468 549 472 +1552 570 187 373 374 +1553 606 413 641 640 +1554 413 610 602 640 +1555 458 467 13 9 +1556 467 458 13 371 +1557 11 422 26 543 +1558 25 17 425 15 +1559 646 536 280 493 +1560 646 624 280 536 +1561 647 430 44 42 +1562 618 544 220 379 +1563 648 6 486 7 +1564 648 6 538 486 +1565 403 633 547 481 +1566 403 328 633 481 +1567 483 127 628 578 +1568 486 7 12 14 +1569 53 56 352 496 +1570 340 288 284 625 +1571 283 340 284 625 +1572 561 352 472 468 +1573 86 450 328 403 +1574 329 403 481 328 +1575 455 288 284 372 +1576 501 288 284 455 +1577 376 530 575 630 +1578 630 376 609 575 +1579 430 479 42 647 +1580 621 405 600 534 +1581 22 28 20 443 +1582 643 238 229 423 +1583 481 633 547 142 +1584 558 428 551 652 +1585 509 611 331 508 +1586 513 514 331 611 +1587 509 513 331 611 +1588 601 9 1 3 +1589 289 288 344 501 +1590 515 32 399 34 +1591 403 321 349 329 +1592 392 229 643 238 +1593 618 445 544 379 +1594 618 587 544 445 +1595 531 613 534 573 +1596 629 153 448 628 +1597 538 473 597 486 +1598 597 473 639 486 +1599 650 31 608 346 +1600 607 505 580 21 +1601 288 455 289 372 +1602 289 455 288 501 +1603 376 530 590 575 +1604 49 594 475 575 +1605 356 279 281 274 +1606 550 209 444 500 +1607 362 412 446 562 +1608 529 433 491 223 +1609 455 372 284 283 +1610 465 501 455 289 +1611 465 289 344 501 +1612 445 209 444 587 +1613 153 642 127 628 +1614 294 385 291 414 +1615 283 625 459 599 +1616 613 531 51 573 +1617 636 573 613 51 +1618 557 621 568 537 +1619 558 551 520 5 +1620 500 209 202 627 +1621 635 200 541 574 +1622 595 200 635 574 +1623 558 652 551 5 +1624 534 579 573 615 +1625 605 575 630 564 +1626 31 346 32 608 +1627 631 424 639 422 +1628 383 346 638 26 +1629 469 575 564 413 +1630 15 560 332 598 +1631 15 554 332 560 +1632 586 557 534 615 +1633 573 586 534 615 +1634 332 543 598 593 +1635 543 332 598 15 +1636 609 575 564 630 +1637 554 631 332 453 +1638 424 554 543 422 +1639 608 346 651 650 +1640 487 495 430 479 +1641 645 621 534 557 +1642 645 621 600 534 +1643 542 491 541 574 +1644 541 635 574 491 +1645 636 644 586 573 +1646 573 586 615 644 +1647 543 634 598 593 +1648 497 127 642 628 +1649 598 543 15 634 +1650 25 15 543 634 +1651 473 519 597 453 +1652 595 574 635 491 +1653 636 51 615 573 +1654 644 573 636 615 +$EndElements diff --git a/test/user/testdata/shark_41_ascii_missing_element_header.msh b/test/user/testdata/shark_41_ascii_missing_element_header.msh new file mode 100644 index 00000000..86a26d34 --- /dev/null +++ b/test/user/testdata/shark_41_ascii_missing_element_header.msh @@ -0,0 +1,2972 @@ +$MeshFormat +4.1 0 8 +$EndMeshFormat +$Entities +0 0 0 1 +0 -0.07334360000000001 -0.08523339999999999 -0.0005566629999999989 0.07028570000000001 0.0819076 0.0752128 0 0 +$EndEntities +$Nodes +1 652 1 652 +3 0 0 652 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +-0.07334359999999999 0.08167480000000001 0.056402 +-0.07291259999999999 0.0537921 0.00170478 +-0.072634 0.0799069 0.0578949 +-0.0715817 0.0520377 0.00292576 +-0.0701949 0.08025690000000001 0.0450431 +-0.06876980000000001 0.060971 0.00326551 +-0.06778000000000001 0.060358 0.00473741 +-0.06727959999999999 0.08092489999999999 0.0425553 +-0.0658074 0.0806443 0.0552302 +-0.064933 0.0788176 0.0453762 +-0.0636555 0.0610198 0.00141989 +-0.0636111 0.0566004 -0.000556663 +-0.0636791 0.0819076 0.0524468 +-0.0623445 0.0580268 0.00335683 +-0.0624856 0.06710579999999999 0.00581638 +-0.0601398 0.0781111 0.0317589 +-0.0599443 0.0685632 0.009924489999999999 +-0.0592787 0.0571239 0.00105116 +-0.0587906 0.07199990000000001 0.0117948 +-0.0575605 0.0730663 0.016213 +-0.057624 0.0811803 0.0403639 +-0.0572339 0.0769387 0.0223219 +-0.0559974 0.0749629 0.0235691 +-0.0542321 0.0763209 0.0344665 +-0.0540672 0.0649483 0.008218130000000001 +-0.0541685 0.06611350000000001 0.00437935 +-0.0532966 0.0805356 0.0466758 +-0.0517252 0.07611850000000001 0.0183218 +-0.0505257 0.06887699999999999 0.0152572 +-0.0503803 0.07726379999999999 0.0406423 +-0.0472855 0.0641041 0.00381053 +-0.0469016 0.0648796 0.00821733 +-0.0474599 0.07272679999999999 0.0265623 +-0.0464733 0.070912 0.0103373 +-0.0444756 0.07556740000000001 0.0221683 +-0.0440208 0.07743129999999999 0.0371107 +-0.0434135 0.0685101 0.0213943 +-0.0425401 0.0668787 0.0159114 +-0.0405353 0.07301630000000001 0.0309862 +-0.0386417 0.073548 0.0160682 +-0.037401 0.0664899 0.0122191 +-0.0358693 0.06894450000000001 0.0243885 +-0.0351058 0.06877709999999999 0.0124837 +-0.0333614 0.07116500000000001 0.0238503 +-0.0325564 0.0696271 0.024504 +-0.032455 0.0625178 0.0200737 +-0.0305469 0.0729973 0.0173921 +-0.0276941 0.06523859999999999 0.0128238 +-0.0272717 0.0628782 0.0141328 +-0.0263428 0.00735496 0.00505748 +-0.0256055 0.00658056 0.00327552 +-0.0252856 0.0610141 0.0227762 +-0.0250237 -0.00678856 0.00359213 +-0.0242889 -0.00589458 0.00589675 +-0.0216872 0.0639735 0.0255561 +-0.0215721 -0.0119744 0.00619585 +-0.0195136 0.0542304 0.0216195 +-0.0168343 0.06495339999999999 0.0236547 +-0.0161373 -0.00420129 0.00881529 +-0.0148726 0.0585475 0.0106707 +-0.0140647 0.0517836 0.0159197 +-0.0142986 0.0543801 0.0051496 +-0.0139611 -0.0178642 0.00651265 +-0.0139803 0.0554055 0.0115694 +-0.0124373 0.0606817 0.0122622 +-0.0127423 0.0580719 0.0285553 +-0.0127412 -0.07042320000000001 0.0234664 +-0.0126173 -0.0801905 0.022154 +-0.0125269 0.0592002 0.0346418 +-0.0122498 -0.080596 0.0191154 +-0.0121442 -0.0691943 0.0191352 +-0.0123618 0.0658492 0.0197519 +-0.0121018 -0.063334 0.0245151 +-0.0118539 0.0462485 0.0243954 +-0.0111067 0.0637388 0.0161162 +-0.0110042 -0.0624802 0.0276395 +-0.0109072 0.046219 0.0183571 +-0.0107037 -0.000325242 0.00950432 +-0.010183 -0.0121386 0.00674337 +-0.009774420000000001 -0.0638147 0.0162637 +-0.0097669 -0.06993340000000001 0.0156591 +-0.00942656 -0.0836042 0.0182705 +-0.009320999999999999 -0.0852334 0.0216727 +-0.00803502 0.0401179 0.0263407 +-0.00857808 -0.0579335 0.0163943 +-0.007931580000000001 -0.0190616 0.0121625 +-0.00782675 0.0573514 0.028038 +-0.00773028 -0.0620746 0.0302044 +-0.00764665 0.0537773 0.00961295 +-0.00721562 -0.0507362 0.0224357 +-0.00717408 -0.0528249 0.0179333 +-0.00651588 -0.00739691 0.013024 +-0.00691116 -0.00014073 0.00823716 +-0.00661131 0.044183 0.0123 +-0.00658663 0.0535365 0.0326225 +-0.00630954 -0.08506569999999999 0.0194796 +-0.00616497 -0.0797841 0.0261073 +-0.00582999 -0.0494502 0.0287705 +-0.00563359 0.0476479 0.00934546 +-0.00506609 -0.0425596 0.0250833 +-0.00453974 -0.0405694 0.0173853 +-0.00447266 0.0319291 0.0205877 +-0.00434886 0.0267225 0.00648417 +-0.00418386 0.0253438 0.008421959999999999 +-0.0041733 -0.0606038 0.0122716 +-0.00385183 0.0479538 0.00869149 +-0.00333705 0.051389 0.031593 +-0.00333565 -0.06938809999999999 0.0119551 +-0.00333748 -0.0650683 0.0110291 +-0.00292457 0.0475597 0.0319288 +-0.00280471 -0.0353375 0.0238411 +-0.00273019 -0.0493159 0.0135756 +-0.00255346 -0.0452657 0.0126112 +-0.00249178 -0.0598565 0.010934 +-0.00247351 -0.0533955 0.0149632 +-0.00280465 0.0288144 0.0300227 +-0.00225175 -0.030519 0.0236922 +-0.00205777 -0.0595101 0.00715068 +-0.0018581 -0.0627033 0.0116048 +-0.00150112 -0.0384203 0.0313885 +-0.00143547 -0.0337232 0.0176227 +-0.00136747 -0.062725 0.0150152 +-0.000884775 -0.0587825 0.0143119 +-0.000624659 -0.0247814 0.0257906 +-0.000489974 0.0225414 0.0188523 +-6.05566e-05 0.0171338 0.0234086 +0.00150381 0.0360475 0.00675461 +0.000282178 -0.0241462 0.0174969 +0.000347869 -0.06752370000000001 0.0324883 +0.000429839 -0.0422219 0.0349169 +0.00028168 -0.0273698 0.0312235 +0.000952705 -0.0267391 0.0143612 +0.00105244 0.0186951 0.00689988 +0.0011109 -0.0779453 0.014663 +0.00137887 0.00842564 0.0258445 +0.00107238 -0.0462225 0.00980545 +0.00158113 -0.0561697 0.005809 +0.00165921 -0.0142314 0.0114909 +0.00169065 -0.00330978 0.027848 +0.0017282 0.0264299 0.00972258 +0.00196109 -0.062067 0.0125082 +0.00198494 -0.0249792 0.0122768 +0.00206797 -0.0322322 0.0125632 +0.00219287 -0.00991015 0.0199027 +0.00223228 -0.065619 0.00972103 +0.00226787 -0.06664 0.0139131 +0.00233081 0.009707510000000001 0.0349608 +0.0023033 -0.0550711 0.0357611 +0.00284591 -0.06958739999999999 0.0109337 +0.00313658 0.0123831 0.0152878 +0.00325266 -0.000639164 0.0164744 +0.00354678 -0.0651674 0.00553443 +0.00434877 0.0392681 0.00656793 +0.0034004 -0.0624097 0.0143354 +0.00410027 0.052311 0.0146156 +0.00425687 -0.0110681 0.0377954 +0.0043501 -0.0020508 0.015115 +0.00444422 -0.0785667 0.0168482 +0.00471578 -0.008727459999999999 0.0133588 +0.00486541 0.0192794 0.0102326 +0.00475235 0.0259901 0.00777948 +0.00497525 -0.0797755 0.0244877 +0.0052286 0.0545416 0.0234287 +0.00513856 -0.0361953 0.00904286 +0.00543656 -0.016404 0.0117933 +0.00521097 0.0361763 0.0357574 +0.00563068 0.0458779 0.0101474 +0.00602624 -0.0598053 0.00448538 +0.00669265 -0.0730234 0.0300997 +0.00671975 -0.0647944 0.0149968 +0.00743572 0.0219428 0.00498754 +0.00806977 -0.06766220000000001 0.0106835 +0.008580020000000001 0.0185363 0.00804532 +0.00900922 -0.0527441 0.0382868 +0.00967438 -0.0310472 0.0412759 +0.009690270000000001 -0.0470756 0.00574739 +0.009825469999999999 -0.0777201 0.0238208 +0.010337 -0.0646559 0.00738197 +0.0103691 -0.0715108 0.0301524 +0.0108524 -0.06519229999999999 0.0107074 +0.0112352 0.0223598 0.00496048 +0.0115762 0.0360388 0.034027 +0.011811 0.0150563 0.0411225 +0.0119389 -0.07108730000000001 0.0142927 +0.011481 0.000850754 0.00890493 +0.0122581 0.0177891 0.00726338 +0.0126044 0.0285097 0.0071727 +0.0126077 -0.0410848 0.00487059 +0.01325 0.0245576 0.00385279 +0.0133342 -0.0301914 0.00695184 +0.0134526 -0.00467313 0.044297 +0.0140263 0.0415073 0.0128325 +0.0139319 -0.0627506 0.0126489 +0.0144402 0.0213321 0.0408733 +0.0145153 -0.0120242 0.00709154 +0.0145254 0.0314471 0.00762861 +0.0143606 -0.0539791 0.00638859 +0.0153705 -0.0588177 0.00913193 +0.0158483 0.0424843 0.0267153 +0.0161677 0.0082135 0.0752128 +0.0160709 -0.0693691 0.0267104 +0.0163112 0.021127 0.00658374 +0.0163956 0.0418119 0.0180916 +0.0166653 0.00513625 0.0449469 +0.0171438 -0.009394380000000001 0.0462661 +0.0174416 -0.0497054 0.0373642 +0.0174198 -0.06569369999999999 0.0159871 +0.0177387 0.0346114 0.0053358 +0.0178439 0.0247259 0.00729322 +0.018247 0.0346901 0.00258831 +0.0182074 -0.0318958 0.0424624 +0.0183988 -0.00142899 0.0496692 +0.0188182 -0.018825 0.0447569 +0.0188285 0.0147456 0.0461032 +0.0188626 0.015416 0.041072 +0.0190811 -0.00419709 0.06868580000000001 +0.0195945 0.0084326 0.064095 +0.0197498 -0.00217441 0.0583864 +0.0198208 0.00539755 0.0587622 +0.0200137 0.0324539 0.00354185 +0.020151 -0.0145671 0.0500049 +0.0203386 -0.00326709 0.07024469999999999 +0.0209148 0.00523036 0.0681576 +0.0208447 0.0121045 0.0546374 +0.0209724 0.009706330000000001 0.0633876 +0.020604 -0.0121123 0.00591309 +0.0212498 -0.0289526 0.00565549 +0.0216078 -0.0380775 0.00479088 +0.0216875 -0.00997672 0.0619769 +0.0220658 0.00705093 0.0456869 +0.0223002 -0.0558455 0.0110476 +0.0223137 -0.0154618 0.0494217 +0.0229336 0.00417573 0.0589573 +0.0231427 0.0278288 0.0125965 +0.0231751 0.027241 0.0309726 +0.0233259 0.0160686 0.00756079 +0.0234095 0.0318943 0.0199392 +0.0234462 -0.00393483 0.0583985 +0.0235915 -0.0597066 0.0170609 +0.0240196 -0.0108777 0.0466362 +0.024123 -0.00330273 0.0464733 +0.0242099 -0.0321428 0.0398591 +0.0244244 0.00347947 0.0416421 +0.024564 -0.0175604 0.0433407 +0.0253979 -0.0453083 0.0344803 +0.0256103 0.0267734 0.0284514 +0.0259312 -0.0445208 0.00878379 +0.025959 -0.0133125 0.00624018 +0.0265967 -0.0369666 0.00635268 +0.0273245 -0.0066598 0.0412078 +0.0277597 -0.0467651 0.0304517 +0.0275944 -0.0515878 0.0207552 +0.0282687 0.0208205 0.0174814 +0.0290859 0.0112094 0.012597 +0.0293048 -0.0474855 0.0256026 +0.0296506 -0.0466043 0.0156453 +0.0304236 0.0134394 0.031696 +0.0304518 -0.0291908 0.00746031 +0.03126 -0.044124 0.016095 +0.0321715 -0.043346 0.0242104 +0.0322352 -0.0402733 0.0141242 +0.0323149 0.01052 0.0200521 +0.0324768 -0.0397188 0.0271188 +0.0325431 -0.0291932 0.0340382 +0.0332479 -0.0329826 0.0117351 +0.0338676 -0.0346121 0.0252676 +0.0341522 -0.00293196 0.033596 +0.0341882 -0.0361716 0.0179088 +0.0344969 -0.0256263 0.0309923 +0.0345138 -0.00958586 0.0123416 +0.0348872 -0.0128566 0.0339912 +0.0349524 -0.0273994 0.0177976 +0.0349556 -0.000677158 0.0209767 +0.0350004 -0.028049 0.008761420000000001 +0.0353194 -0.0100316 0.0154749 +0.0354214 -0.0195455 0.0173172 +0.0355775 -0.0309821 0.0107592 +0.0360305 -0.0150581 0.0232372 +0.0363938 -0.0285041 0.0132933 +0.0374738 -0.00607371 0.0123945 +0.041317 -0.0210454 0.0131228 +0.0425886 -0.0120136 0.0129537 +0.0475164 -0.00753527 0.00853843 +0.0492593 -0.00704914 0.009380670000000001 +0.0496752 -0.0170405 0.0106038 +0.0498676 -0.0259318 0.00619626 +0.052402 -0.022331 0.00866719 +0.0516897 -0.011391 0.0103437 +0.0559595 -0.0106346 0.00698866 +0.0596531 -0.0214295 0.0059579 +0.066312 -0.0158462 0.00759335 +0.0672852 -0.00331292 0.00667068 +0.0687074 -0.0027598 0.00829441 +0.0687083 -0.008451500000000001 0.00881385 +0.07028570000000001 -0.00694567 0.00665748 +0.02471 0.00101921 0.00688758 +0.00641783 -0.0341512 0.0233596 +0.024018 0.00854392 0.00722419 +0.0251696 0.009421270000000001 0.00784613 +-0.019815 0.0686939 0.0189821 +0.0416697 -0.017118 0.00864259 +-0.00440288 -0.06984319999999999 0.0205811 +-0.0033606 0.0600219 0.0217676 +0.0268544 0.00322876 0.008082499999999999 +0.00855449 0.0107052 0.00928038 +0.0219179 0.00585482 0.0121236 +0.0199208 0.0175811 0.0336776 +0.0210521 -0.0362113 0.0256186 +0.0339797 -0.00194129 0.0163861 +0.03202 0.000337126 0.0126992 +0.0119633 0.0163586 0.0147908 +0.0248778 0.0056119 0.0321775 +0.00892971 -0.0563678 0.0287948 +0.0174837 0.027107 0.0210333 +-0.0170518 0.00346089 0.00554363 +0.0144974 -0.0120686 0.0314959 +0.00336155 -0.00103205 0.0364574 +0.00707711 -0.0204903 0.0185209 +0.010517 -0.00309481 0.0232445 +-0.00559352 0.0373259 0.0172753 +-0.00523735 -0.0230725 0.0111224 +0.0151072 -0.0538804 0.0213778 +0.0347571 -0.0188174 0.0105515 +0.0278657 -0.0183642 0.0156758 +-0.00338013 -0.0543805 0.0329679 +-0.0196332 0.0593213 0.0251138 +0.06481629999999999 -0.0143432 0.00627944 +-0.00336175 -0.0187472 0.00979996 +-0.0059938 -0.0214388 0.00941436 +0.0204933 0.0262773 0.00994486 +0.0153554 0.00838654 0.0105168 +-0.064082 0.064994 0.00682263 +-0.0406296 0.0703091 0.0249838 +-0.0197677 0.0563929 0.0156108 +-0.0506931 0.0781816 0.0304629 +0.0171972 -0.00100568 0.011485 +0.0314619 -0.0225976 0.00774901 +-0.00980694 0.0515267 0.0104574 +-0.00435185 0.0493969 0.0137744 +0.0449063 -0.0117353 0.00859937 +0.00159087 -0.0450385 0.027858 +-0.00469537 -0.06372510000000001 0.0233918 +0.0424219 -0.0285632 0.00857374 +0.0603894 -0.00835109 0.009350529999999999 +-0.0147113 -0.0156046 0.009183759999999999 +-0.0528157 0.0611754 0.00480955 +-0.0173765 -0.008871489999999999 0.00520522 +0.0108104 0.02268 0.0130558 +-0.00899905 -0.0208443 0.00915416 +-0.0449914 0.0768094 0.0302276 +-0.0408502 0.06658 0.008368489999999999 +-0.0199988 -0.0118916 0.004906 +0.00337131 0.0455887 0.0238561 +0.00477413 -0.0721541 0.0211645 +-0.00344193 -0.049333 0.032475 +0.0427245 -0.0268877 0.00738607 +0.0272704 -0.0238375 0.00669928 +-0.00610544 -0.0476638 0.0181008 +-0.00760153 0.0503529 0.00747858 +0.0131109 -0.0422224 0.0405109 +0.00214561 -0.0490294 0.0151357 +-0.0598224 0.0805424 0.0511855 +-0.0204542 0.0588165 0.013102 +0.059357 -0.0190886 0.00813027 +-0.00100716 0.0422264 0.0325724 +0.0325535 -0.0244764 0.012522 +-0.000431427 -0.0574818 0.0137747 +0.0114251 0.0275734 0.00440942 +0.00337666 -0.0559724 0.0148659 +-0.0262911 0.0586227 0.0207785 +-0.0699467 0.0813567 0.0499003 +0.0494602 -0.0133111 0.00757754 +0.00758285 0.0333008 0.0104911 +0.00657287 0.032122 0.00603963 +0.000332803 -0.0511328 0.0180756 +-0.021764 0.0620607 0.0118108 +-0.0454672 0.075167 0.035911 +0.00139884 0.045926 0.0128133 +0.0176314 0.0311493 0.00370344 +-0.0159418 -0.0158578 0.00793814 +-0.0229387 0.06916410000000001 0.0166572 +-0.00133409 -0.0449329 0.0187829 +-0.0538019 0.0611146 0.00198764 +0.0305208 -0.00256491 0.0101919 +0.0623596 -0.00697151 0.00683979 +0.0236819 -0.00777996 0.0526871 +0.0118138 -0.0144241 0.0430193 +0.0137156 -0.00365078 0.00732253 +-0.0257884 0.0686739 0.0150694 +-0.0530331 0.060812 0.00248197 +-0.000421194 -0.0523335 0.008791770000000001 +0.0193846 -0.00072024 0.0649221 +0.00485856 0.0133946 0.0114741 +-0.0053823 -0.0743714 0.0141262 +0.016958 0.0166471 0.00740593 +0.0429338 -0.0266961 0.0110582 +-0.06504749999999999 0.05473 0.00191127 +0.00924818 0.0356698 0.00715588 +-0.042468 0.0652669 0.00790867 +0.00699205 0.0348997 0.00576165 +-0.012123 0.00171435 0.00688121 +0.017741 0.00126373 0.0717161 +-0.00477874 -0.0228765 0.0123522 +-0.05496 0.0793832 0.0329037 +-0.0253736 -0.000654191 0.00342534 +0.0220159 -0.0128389 0.0555838 +0.0187915 0.00366305 0.06539010000000001 +-0.0635923 0.0794618 0.0351284 +0.0187293 0.00901455 0.0689246 +-0.0507436 0.0790633 0.0364811 +0.00440962 0.0291856 0.00589534 +-0.0610541 0.08157639999999999 0.0467801 +-0.0264169 0.06418980000000001 0.0180225 +0.0590681 -0.0129818 0.009692930000000001 +0.0316732 -0.013669 0.008927310000000001 +-0.0368828 0.0732351 0.028231 +0.0147007 -0.0293577 0.0425282 +-0.00226105 0.042112 0.008184220000000001 +-0.022404 0.068624 0.0211714 +0.018834 0.0296379 0.0101126 +0.0545664 -0.023882 0.00596013 +-0.0610274 0.0626039 0.00623226 +0.0209345 -0.0123916 0.0558755 +-0.064258 0.0639612 0.00701622 +-0.0530259 0.07099660000000001 0.0104874 +-0.000350232 0.0328643 0.009503569999999999 +0.0179821 0.0260225 0.00525665 +-0.071629 0.0809096 0.0500374 +0.0431333 -0.00662611 0.0109755 +-0.0367738 0.072104 0.0272887 +-0.00147996 0.0424733 0.00778004 +-0.0489442 0.0792518 0.0424775 +0.0178184 0.008309230000000001 0.0698262 +-0.00256208 -0.0518644 0.0119693 +-0.0024457 0.0347988 0.0115191 +-0.0226391 0.067054 0.0236986 +-0.0250562 0.070839 0.0181046 +0.0157661 -0.010775 0.0444953 +-0.0587069 0.0610686 0.00549325 +-0.0561989 0.0607157 0.00436391 +0.0028322 0.0311045 0.0076099 +-0.061857 0.079748 0.0514834 +-0.0580072 0.07448539999999999 0.0170926 +0.017366 0.0281829 0.00449304 +0.0175246 0.0303053 0.00632184 +-0.0583716 0.0812348 0.0494755 +-0.06276379999999999 0.08110589999999999 0.0418948 +0.009583370000000001 0.0391723 0.00889538 +0.0164997 0.0327763 0.00400793 +-0.0100537 -0.019407 0.0104569 +0.0535082 -0.023589 0.00757618 +-0.0184567 0.0672393 0.0165986 +-0.0660887 0.06395149999999999 0.00557639 +-0.008500499999999999 0.0591911 0.0132991 +0.0527123 -0.00658592 0.00801901 +0.00664445 0.0147496 0.00979726 +-0.0323364 0.06468409999999999 0.013176 +-0.06849810000000001 0.0817682 0.0541475 +0.0424951 -0.00680449 0.0104665 +-0.01583 0.06382989999999999 0.0140017 +-0.0408586 0.07478079999999999 0.0276312 +-0.0213675 0.00505684 0.00440033 +-0.0609542 0.0784149 0.029815 +0.0458286 -0.0196104 0.0115924 +0.0619857 -0.0044448 0.00717137 +-0.0549453 0.0736446 0.0144159 +-0.0660739 0.0797747 0.0511232 +-0.0150243 -0.0138696 0.00597473 +-0.0208919 0.06642729999999999 0.014553 +-0.0583912 0.07667309999999999 0.0277458 +-0.00499489 -0.0492059 0.0154875 +-0.0177596 -0.0149926 0.00640227 +-0.0656257 0.0638276 0.00437301 +-0.00111824 -0.0505712 0.010634 +-0.0234714 0.0595273 0.0150887 +-0.0117477 -0.00786715 0.0107629 +-0.0329423 0.0662408 0.012525 +-0.0588644 0.0778049 0.0265316 +-0.038272 0.07101209999999999 0.0277124 +0.0147178 0.0228905 0.00513556 +-0.00242697 -0.0228032 0.0106496 +-0.00998317 -0.0196685 0.00798312 +0.00194711 0.0338412 0.00734265 +-0.0101071 0.0571173 0.0108272 +-0.000192036 0.0305177 0.010316 +-0.06622359999999999 0.0609953 0.00234663 +-0.0383437 0.071981 0.0290737 +0.0464353 -0.0271448 0.00729223 +-0.0113654 0.0558876 0.00985606 +-0.0600686 0.0581853 0.00037707 +0.0184892 0.00651809 0.072001 +-0.0272353 0.0661385 0.0125002 +0.0386787 -0.009397559999999999 0.0110365 +-0.00702298 -0.0554164 0.0301677 +-0.0387296 0.0725599 0.0291973 +-0.0195884 -0.009713039999999999 0.00731553 +0.0009803979999999999 0.0340005 0.008311529999999999 +-0.00251349 -0.0493306 0.0137872 +-0.0208118 0.00468072 0.00662791 +0.0145465 0.0247675 0.00685396 +0.0539643 -0.00601143 0.00911787 +0.0615879 -0.00432066 0.00875869 +-0.0649217 0.0800024 0.0383643 +0.00460493 0.008497380000000001 0.0127005 +-0.0606311 0.0803611 0.0379233 +-0.00316884 0.0400824 0.00969248 +-0.0308482 0.067467 0.0126012 +0.0120049 0.00511369 0.00824306 +0.0117314 0.0134932 0.00784586 +0.0067401 0.0222359 0.00786688 +0.000365941 0.0444987 0.0334101 +0.00589042 0.0427357 0.0325284 +0.0134556 0.013691 0.0071386 +0.0155774 0.00572549 0.00675779 +-0.0442054 0.0654197 0.00607699 +0.00863004 0.0184766 0.00878081 +-0.0111016 -0.0170398 0.0107756 +-0.0162643 0.06208 0.0123266 +-0.06706429999999999 0.0628756 0.0047451 +-0.0673064 0.07917689999999999 0.0489333 +-0.0566743 0.0588231 0.00264455 +-0.07138410000000001 0.080001 0.0523997 +-0.0690781 0.0794039 0.0521145 +-0.0589744 0.07029879999999999 0.0123753 +-0.0108026 0.05228 0.00636676 +-0.0113486 0.0541547 0.00728553 +-0.0299136 0.06862409999999999 0.0165753 +0.0505332 -0.0225927 0.00635398 +0.0180077 0.0031318 0.07043870000000001 +-0.0235313 0.0640143 0.012641 +-0.0235569 0.00584404 0.00381922 +0.0384718 -0.0113423 0.0144484 +0.0182407 0.00232532 0.0728388 +-0.0235752 0.00407866 0.00373027 +-0.011585 0.0522432 0.00647843 +0.0400312 -0.00904366 0.0126741 +-0.0178591 -0.000359808 0.00797485 +-0.067167 0.06255139999999999 0.00392853 +-0.0596438 0.0779391 0.0290601 +0.0013543 0.0302152 0.00901705 +0.0168301 0.00522322 0.0737244 +0.0174324 0.00448014 0.0738384 +-0.0618546 0.0649931 0.00590465 +0.0194429 0.0304209 0.00452872 +-0.0236633 0.0648084 0.0124456 +-0.00249493 -0.0562542 0.012985 +-0.0025263 -0.0246783 0.0125409 +-0.0396392 0.0718092 0.02876 +-0.0158083 -0.0164708 0.00645267 +0.016879 0.0245859 0.0055459 +-0.06884990000000001 0.0811361 0.0461884 +0.0290982 -0.00647478 0.008279069999999999 +-0.041817 0.0761358 0.0343691 +-0.0642688 0.0653922 0.00517065 +-0.0162175 0.00239503 0.00694561 +0.00467524 0.0360758 0.00643588 +-0.0222973 0.0035638 0.00646752 +-0.0708092 0.0801688 0.0482801 +-0.0549524 0.07870829999999999 0.0296023 +-0.06310540000000001 0.0672415 0.00811831 +-0.0155444 -0.0163359 0.0060847 +-0.0574097 0.07880470000000001 0.0473507 +-0.0558952 0.0591814 0.001764 +-0.0177409 0.0619627 0.0144786 +-0.00178349 -0.0487397 0.0125937 +-0.0111058 0.0522074 0.008299040000000001 +-0.0260139 0.00360897 0.00461987 +-0.0204566 0.00423454 0.00564674 +0.00612936 0.0370467 0.00680554 +0.010446 0.0313554 0.00705031 +-0.0569353 0.05965 0.00118235 +-0.0506685 0.0625792 0.00279292 +-0.0249761 0.00485573 0.00443819 +0.0172421 0.00725128 0.07382619999999999 +-0.0219613 0.06430039999999999 0.0138184 +-0.00260185 -0.0513557 0.0142694 +-0.0167422 0.00259292 0.00779623 +0.00214524 0.0341103 0.00650831 +-0.0236765 0.00572293 0.004305 +-0.0616879 0.0784644 0.0353636 +-0.0125522 0.0533024 0.00573952 +-0.00373263 -0.048886 0.014509 +-0.00253347 -0.0472982 0.0131992 +-0.0128746 -0.017623 0.00940414 +-5.43548e-05 0.0393803 0.00728201 +-0.0258702 0.00405717 0.00525282 +0.0183599 0.0265636 0.00640112 +0.0459896 -0.0257989 0.0100883 +-0.0295424 0.06805940000000001 0.0247957 +-0.0245383 0.0634107 0.0123732 +0.0066096 0.0377811 0.00691952 +-0.0450015 0.0646553 0.00575343 +-0.0622505 0.0661482 0.00839783 +-0.0256248 0.0608105 0.0161665 +0.017488 0.00853314 0.07209649999999999 +-0.0596734 0.07050969999999999 0.009924850000000001 +-0.06657979999999999 0.06286890000000001 0.00493615 +-0.0624322 0.0664941 0.0080812 +0.0436037 -0.00911409 0.009504510000000001 +-0.0258241 0.00183578 0.00455937 +-0.07027029999999999 0.07969130000000001 0.0546337 +-0.027947 0.06304949999999999 0.0231884 +-0.0601839 0.07046330000000001 0.0106076 +-0.019796 -0.0130118 0.0069497 +-0.0183149 0.06305479999999999 0.012418 +-0.0302535 0.0701272 0.02364 +-0.0574291 0.07908510000000001 0.0314511 +-0.0506885 0.0650762 0.00396145 +-0.021101 0.0616869 0.0137094 +-0.0331684 0.0670427 0.023997 +0.0134393 0.00644533 0.00718965 +-0.0111807 -0.0194906 0.00818236 +-0.0255718 0.00304117 0.00332801 +-0.0126697 -0.015488 0.00653208 +-0.0247074 0.00660999 0.00551935 +0.0173416 0.0031807 0.0727906 +0.0172416 0.0236783 0.00588169 +0.0190309 0.0293428 0.00437137 +0.016715 0.00646681 0.0747173 +-0.0362286 0.072292 0.023504 +-0.0193589 -0.00042516 0.00470745 +-0.0218861 0.06436310000000001 0.0125137 +-0.0102557 0.0512168 0.00711881 +0.0404202 -0.00631757 0.0116411 +0.0462272 -0.00679819 0.0101561 +-0.0259792 0.0656558 0.0150971 +0.0162732 0.0229634 0.00624384 +0.00353474 0.0364474 0.008433390000000001 +4.6368e-06 0.0388726 0.009730829999999999 +-0.0216501 0.0633078 0.012475 +-0.06535530000000001 0.0635995 0.0060088 +-0.0129397 0.0533345 0.00604151 +-0.00189413 -0.0244631 0.013557 +-0.0610974 0.0673557 0.00916116 +0.0169636 0.00823874 0.0726305 +-0.0262169 0.00566462 0.00486021 +-0.00105663 -0.050339 0.013034 +-0.0522352 0.0618469 0.00239028 +-0.06586110000000001 0.0623674 0.00600767 +-0.0308719 0.0671807 0.0240148 +-0.0271033 0.0631674 0.0232081 +0.000463176 0.0377435 0.00713404 +0.0197653 -0.0105149 0.0573133 +-0.0261272 0.00574879 0.00514751 +-0.0256133 0.00236555 0.00535812 +0.0395658 -0.00664927 0.0115095 +-0.0346515 0.0704144 0.0260764 +-0.0676857 0.0619198 0.00410476 +-0.0352382 0.07226829999999999 0.0261851 +-0.0489272 0.0632235 0.00329626 +-0.0514659 0.0617489 0.00295197 +-0.070483 0.0805389 0.0464472 +$EndNodes +$Elements +3 0 4 1654 +1 26 15 543 25 +2 227 308 190 188 +3 203 353 199 163 +4 331 305 504 150 +5 142 328 128 138 +6 490 439 18 571 +7 364 289 287 414 +8 296 336 304 298 +9 564 419 300 381 +10 398 569 373 591 +11 486 473 639 422 +12 338 89 566 489 +13 332 554 543 424 +14 80 67 71 302 +15 149 146 109 108 +16 98 90 375 342 +17 341 308 325 313 +18 147 314 126 116 +19 124 318 156 131 +20 245 322 206 308 +21 348 311 516 186 +22 135 150 319 151 +23 147 314 307 311 +24 464 588 301 528 +25 461 33 35 333 +26 196 192 373 314 +27 108 81 302 122 +28 366 258 227 357 +29 511 107 512 353 +30 146 170 354 172 +31 297 175 156 130 +32 130 297 175 308 +33 318 159 319 195 +34 154 123 122 342 +35 261 308 259 260 +36 132 142 128 318 +37 241 250 240 205 +38 226 227 248 324 +39 575 609 475 49 +40 375 91 123 90 +41 260 308 255 251 +42 517 612 63 482 +43 120 117 131 297 +44 318 131 297 156 +45 147 319 311 307 +46 131 120 297 130 +47 120 297 111 117 +48 308 174 206 360 +49 148 313 325 175 +50 148 313 175 174 +51 302 80 122 81 +52 107 353 511 110 +53 322 231 198 197 +54 61 58 564 57 +55 240 386 212 221 +56 121 297 143 117 +57 121 297 117 111 +58 307 235 314 182 +59 307 314 166 182 +60 417 308 175 316 +61 308 175 360 417 +62 601 9 458 1 +63 459 429 536 599 +64 211 242 206 308 +65 528 588 301 356 +66 316 297 308 175 +67 197 188 308 228 +68 231 308 228 197 +69 231 197 322 308 +70 188 197 308 361 +71 322 361 308 197 +72 259 308 256 255 +73 298 306 304 299 +74 302 342 146 122 +75 251 322 245 308 +76 298 306 299 236 +77 342 302 169 129 +78 157 319 331 150 +79 190 195 324 227 +80 146 342 354 154 +81 190 297 308 324 +82 236 254 306 299 +83 354 179 201 322 +84 308 297 188 361 +85 361 188 164 297 +86 195 165 190 318 +87 307 215 257 235 +88 194 235 215 307 +89 174 129 148 313 +90 169 313 129 174 +91 322 255 251 201 +92 366 265 308 258 +93 227 308 258 366 +94 258 308 249 265 +95 227 308 228 258 +96 448 192 373 196 +97 228 308 249 258 +98 296 298 514 336 +99 125 150 348 126 +100 125 160 348 150 +101 244 264 242 316 +102 264 316 244 271 +103 224 233 225 219 +104 107 353 163 199 +105 217 223 219 225 +106 308 174 313 206 +107 206 313 179 174 +108 241 230 212 233 +109 241 233 212 218 +110 267 278 312 273 +111 267 312 262 273 +112 206 179 322 245 +113 242 245 206 308 +114 144 319 159 157 +115 265 308 266 272 +116 218 219 392 233 +117 264 324 316 271 +118 324 308 264 316 +119 297 318 117 131 +120 128 117 318 124 +121 354 207 201 177 +122 207 177 354 184 +123 155 163 353 203 +124 131 297 156 130 +125 395 330 236 202 +126 164 142 318 190 +127 253 314 234 311 +128 307 314 147 166 +129 331 234 253 254 +130 306 236 298 331 +131 156 297 316 175 +132 324 319 318 316 +133 297 324 316 308 +134 373 314 102 125 +135 167 155 378 192 +136 278 324 272 269 +137 278 276 272 324 +138 319 159 157 336 +139 267 257 312 243 +140 307 215 243 257 +141 156 297 318 316 +142 207 354 170 184 +143 124 144 139 156 +144 267 312 250 243 +145 144 151 139 319 +146 318 316 319 144 +147 316 139 319 144 +148 139 144 316 156 +149 316 191 312 319 +150 316 191 317 156 +151 313 308 175 174 +152 253 234 331 311 +153 331 395 234 236 +154 272 265 308 366 +155 103 140 133 510 +156 235 199 246 314 +157 246 237 314 199 +158 144 151 319 157 +159 92 157 151 144 +160 92 159 157 144 +161 395 234 236 330 +162 395 330 202 348 +163 348 330 202 209 +164 324 312 316 271 +165 266 308 324 272 +166 324 366 308 227 +167 242 264 245 308 +168 272 266 269 324 +169 135 151 319 139 +170 40 35 28 29 +171 88 148 129 342 +172 325 342 148 88 +173 314 116 147 166 +174 77 353 320 94 +175 331 262 319 306 +176 319 317 139 316 +177 450 329 482 328 +178 183 307 147 166 +179 188 361 176 197 +180 169 179 313 174 +181 314 196 348 373 +182 102 84 116 353 +183 102 77 84 353 +184 191 147 319 317 +185 307 262 257 312 +186 307 257 246 235 +187 307 257 262 246 +188 128 318 144 124 +189 246 314 237 253 +190 314 203 237 234 +191 142 128 318 138 +192 253 237 234 314 +193 306 319 331 336 +194 307 314 235 246 +195 316 250 312 191 +196 450 403 349 329 +197 121 297 101 143 +198 382 164 101 297 +199 369 198 322 193 +200 264 266 324 269 +201 322 354 170 207 +202 322 170 193 207 +203 353 84 116 110 +204 70 302 68 83 +205 331 311 234 395 +206 323 493 282 301 +207 269 278 324 271 +208 278 312 324 271 +209 207 170 180 184 +210 207 170 193 180 +211 325 130 175 308 +212 146 354 170 154 +213 354 302 342 146 +214 161 348 510 181 +215 182 314 199 235 +216 322 354 369 170 +217 231 207 322 198 +218 313 322 375 341 +219 375 361 341 322 +220 322 207 193 198 +221 297 143 164 101 +222 221 213 240 232 +223 190 188 308 297 +224 341 361 375 382 +225 341 308 313 322 +226 134 158 184 354 +227 247 308 261 249 +228 263 308 260 251 +229 318 319 159 144 +230 309 262 306 319 +231 250 204 243 312 +232 448 192 167 378 +233 37 333 620 35 +234 37 33 333 35 +235 297 318 316 324 +236 167 448 378 153 +237 212 218 233 219 +238 88 325 342 494 +239 246 307 314 253 +240 307 253 246 262 +241 126 311 150 348 +242 388 611 336 514 +243 348 234 420 314 +244 236 254 331 306 +245 348 314 311 234 +246 211 308 360 417 +247 373 102 320 125 +248 316 250 191 438 +249 250 205 191 438 +250 254 262 306 309 +251 254 309 306 310 +252 299 254 306 310 +253 331 262 306 254 +254 292 294 295 293 +255 194 307 215 204 +256 304 306 384 299 +257 267 312 257 262 +258 353 192 378 155 +259 319 159 336 195 +260 353 192 373 378 +261 336 185 388 195 +262 312 250 271 267 +263 271 250 312 316 +264 261 249 308 265 +265 268 308 265 261 +266 247 308 249 228 +267 227 195 324 226 +268 366 324 415 337 +269 337 366 324 357 +270 190 195 318 324 +271 156 318 124 144 +272 263 266 308 264 +273 251 263 308 264 +274 197 198 322 369 +275 154 354 369 342 +276 188 308 228 227 +277 79 328 138 92 +278 316 317 139 156 +279 360 175 308 174 +280 255 251 308 322 +281 255 256 252 308 +282 247 228 231 308 +283 247 308 231 256 +284 134 149 394 354 +285 83 162 96 302 +286 161 373 140 348 +287 88 67 302 68 +288 302 97 88 68 +289 512 166 314 182 +290 420 192 314 234 +291 348 330 420 234 +292 192 314 234 203 +293 91 123 105 115 +294 394 70 302 81 +295 309 273 262 319 +296 319 262 312 273 +297 67 302 68 70 +298 271 278 312 267 +299 66 57 326 58 +300 188 136 176 361 +301 157 331 185 504 +302 136 361 188 164 +303 244 250 271 316 +304 71 302 67 70 +305 244 213 232 240 +306 81 302 71 70 +307 354 149 108 146 +308 314 237 203 199 +309 506 378 435 629 +310 244 438 316 213 +311 97 302 169 162 +312 244 316 438 250 +313 313 129 342 169 +314 382 113 101 164 +315 506 435 378 94 +316 91 123 85 105 +317 308 264 245 251 +318 242 264 308 316 +319 450 349 482 329 +320 314 373 348 125 +321 92 138 159 144 +322 395 311 234 348 +323 278 273 324 312 +324 373 378 435 320 +325 147 311 319 135 +326 126 311 135 150 +327 126 135 311 147 +328 314 348 311 126 +329 83 302 82 70 +330 378 435 629 373 +331 195 159 165 318 +332 316 312 324 319 +333 156 175 316 387 +334 336 298 514 331 +335 88 342 129 302 +336 319 307 331 311 +337 253 314 311 307 +338 311 331 253 307 +339 297 341 308 130 +340 314 348 126 125 +341 147 314 311 126 +342 61 339 99 338 +343 250 204 312 191 +344 305 185 508 331 +345 211 242 308 316 +346 211 308 417 316 +347 213 316 211 417 +348 214 215 230 204 +349 244 316 242 211 +350 244 211 213 316 +351 465 501 344 502 +352 108 354 302 394 +353 313 129 148 342 +354 337 324 415 248 +355 337 258 366 357 +356 121 101 297 111 +357 382 101 111 297 +358 157 159 185 336 +359 226 336 195 324 +360 307 262 331 253 +361 307 262 319 331 +362 331 254 253 262 +363 248 336 552 296 +364 319 324 195 336 +365 248 296 226 336 +366 324 248 336 552 +367 147 183 191 307 +368 282 281 276 323 +369 281 323 282 301 +370 109 119 105 122 +371 297 143 117 318 +372 109 122 105 80 +373 308 366 324 272 +374 297 318 324 190 +375 297 190 164 318 +376 214 204 230 212 +377 224 212 214 230 +378 297 143 318 164 +379 264 308 324 266 +380 264 269 324 271 +381 132 117 143 318 +382 130 297 341 120 +383 341 130 120 98 +384 277 343 356 279 +385 325 308 175 313 +386 109 81 108 122 +387 109 122 108 146 +388 348 234 395 330 +389 341 111 120 297 +390 341 100 98 120 +391 341 111 100 120 +392 226 336 324 248 +393 318 319 324 195 +394 275 270 324 309 +395 309 336 324 319 +396 552 270 336 324 +397 273 309 275 324 +398 403 328 329 450 +399 382 111 341 297 +400 361 322 308 341 +401 361 341 308 297 +402 342 85 73 90 +403 342 73 85 80 +404 323 324 366 276 +405 361 297 164 382 +406 96 82 83 302 +407 45 647 44 42 +408 179 354 201 177 +409 53 621 54 347 +410 117 124 131 318 +411 156 144 316 318 +412 369 198 193 141 +413 342 302 88 67 +414 67 80 342 302 +415 73 80 342 67 +416 342 73 67 76 +417 372 528 289 285 +418 285 528 289 287 +419 355 98 325 494 +420 122 119 105 123 +421 394 82 134 302 +422 494 88 76 342 +423 109 81 122 80 +424 447 580 503 505 +425 114 118 141 145 +426 311 150 319 135 +427 108 122 302 146 +428 204 307 183 194 +429 191 204 307 183 +430 382 101 100 111 +431 382 111 100 341 +432 318 159 138 144 +433 588 281 301 356 +434 87 61 77 57 +435 318 159 165 138 +436 7 12 2 486 +437 316 191 319 317 +438 208 196 449 445 +439 322 369 354 313 +440 354 158 177 162 +441 354 169 162 179 +442 313 369 354 342 +443 179 162 354 177 +444 130 98 341 355 +445 325 130 341 355 +446 337 357 324 248 +447 324 357 227 248 +448 588 281 464 301 +449 375 341 382 98 +450 454 75 61 155 +451 353 77 84 74 +452 331 305 185 504 +453 311 331 319 150 +454 378 339 167 106 +455 318 190 142 165 +456 138 142 165 318 +457 18 12 397 14 +458 298 514 331 513 +459 118 137 141 168 +460 298 331 236 395 +461 395 298 331 513 +462 93 157 92 159 +463 354 158 184 177 +464 151 157 92 93 +465 78 93 151 92 +466 378 448 629 153 +467 102 314 126 125 +468 126 116 314 102 +469 61 72 303 75 +470 39 461 350 553 +471 350 39 33 461 +472 311 331 513 395 +473 311 331 305 509 +474 353 102 314 116 +475 204 215 243 307 +476 106 153 167 378 +477 97 162 83 302 +478 107 353 199 512 +479 297 188 164 190 +480 147 319 139 135 +481 77 353 87 74 +482 353 203 199 314 +483 512 314 353 199 +484 37 38 29 35 +485 485 140 373 125 +486 398 448 373 196 +487 196 570 373 398 +488 324 248 552 415 +489 415 270 552 324 +490 52 57 594 564 +491 285 289 414 287 +492 438 250 205 240 +493 524 425 25 17 +494 29 25 524 425 +495 87 77 61 353 +496 93 92 138 159 +497 93 92 79 138 +498 203 192 353 155 +499 192 353 314 203 +500 88 302 129 97 +501 169 342 354 302 +502 147 319 317 139 +503 435 426 629 373 +504 197 168 369 176 +505 369 176 361 197 +506 157 151 319 150 +507 307 319 312 191 +508 312 307 191 204 +509 628 373 441 374 +510 513 331 311 509 +511 49 594 413 46 +512 303 163 87 61 +513 146 342 154 122 +514 274 366 415 337 +515 274 258 366 337 +516 87 57 74 66 +517 304 306 336 384 +518 204 250 205 191 +519 110 74 66 87 +520 163 87 61 353 +521 204 205 250 241 +522 387 438 213 316 +523 150 160 348 311 +524 313 369 342 375 +525 313 322 369 375 +526 97 129 169 302 +527 504 305 393 150 +528 181 348 500 187 +529 610 527 42 44 +530 44 527 42 620 +531 311 305 456 509 +532 311 509 456 516 +533 365 512 166 116 +534 116 512 166 314 +535 509 305 508 331 +536 322 369 193 170 +537 535 526 581 632 +538 182 314 512 199 +539 497 441 373 540 +540 37 42 46 527 +541 500 209 187 348 +542 312 257 307 243 +543 323 366 281 276 +544 348 420 209 196 +545 366 279 276 272 +546 202 500 186 348 +547 386 406 221 232 +548 64 526 62 489 +549 336 159 185 195 +550 404 24 559 335 +551 404 24 607 559 +552 384 336 552 270 +553 244 240 438 213 +554 244 438 240 250 +555 430 461 620 333 +556 461 333 35 620 +557 61 564 64 334 +558 381 437 47 413 +559 279 277 265 258 +560 279 277 258 274 +561 186 500 181 348 +562 140 510 348 160 +563 377 410 36 350 +564 202 330 236 209 +565 380 345 614 468 +566 99 339 378 106 +567 378 106 418 99 +568 378 448 373 629 +569 194 235 307 182 +570 194 307 166 182 +571 194 307 183 166 +572 353 373 320 378 +573 68 97 83 302 +574 347 496 604 476 +575 161 181 411 373 +576 570 374 400 368 +577 40 38 35 29 +578 364 289 327 528 +579 324 309 319 273 +580 353 378 320 94 +581 358 91 471 375 +582 134 394 302 354 +583 394 149 108 354 +584 172 354 146 149 +585 382 358 471 375 +586 101 382 90 358 +587 651 346 638 390 +588 382 90 100 101 +589 334 594 564 475 +590 369 361 375 322 +591 322 197 369 361 +592 342 325 98 494 +593 325 313 148 342 +594 342 325 375 98 +595 115 369 123 367 +596 342 98 76 494 +597 369 375 576 115 +598 353 512 116 314 +599 336 304 552 296 +600 336 306 304 298 +601 226 514 336 296 +602 108 302 81 394 +603 181 411 373 374 +604 26 440 571 383 +605 26 383 346 440 +606 211 360 308 206 +607 87 74 57 77 +608 358 113 101 382 +609 195 388 336 226 +610 241 233 218 238 +611 155 339 378 353 +612 345 79 468 476 +613 213 316 417 175 +614 387 316 213 175 +615 312 307 262 319 +616 435 485 426 373 +617 435 373 125 485 +618 299 310 306 384 +619 26 425 25 34 +620 118 114 367 434 +621 26 34 25 608 +622 223 222 529 392 +623 527 38 37 35 +624 37 527 46 38 +625 342 123 90 375 +626 342 123 85 90 +627 335 350 33 35 +628 350 461 33 35 +629 85 91 90 123 +630 259 247 308 261 +631 629 628 448 373 +632 633 142 328 128 +633 629 497 628 373 +634 303 61 87 72 +635 236 254 234 331 +636 341 98 325 355 +637 373 570 400 569 +638 398 570 373 569 +639 49 413 527 46 +640 49 46 527 457 +641 49 626 48 527 +642 241 204 243 250 +643 49 527 48 457 +644 392 218 233 238 +645 233 392 238 223 +646 178 198 197 141 +647 198 197 141 369 +648 364 290 287 528 +649 419 381 564 413 +650 92 78 79 59 +651 192 373 314 353 +652 386 406 238 423 +653 367 369 137 391 +654 437 413 419 606 +655 413 437 47 606 +656 239 252 322 255 +657 454 61 339 155 +658 34 466 425 29 +659 221 386 232 240 +660 60 64 489 484 +661 484 65 60 64 +662 212 386 218 221 +663 241 240 386 212 +664 241 205 240 212 +665 607 24 16 470 +666 620 42 37 527 +667 37 333 42 620 +668 95 87 66 69 +669 113 164 382 361 +670 410 30 432 21 +671 371 1 522 458 +672 527 47 43 40 +673 596 425 17 15 +674 393 456 160 311 +675 110 95 87 66 +676 160 311 456 516 +677 512 511 365 166 +678 353 511 365 512 +679 128 144 318 138 +680 341 130 325 308 +681 87 61 57 58 +682 419 58 564 72 +683 414 289 327 364 +684 320 378 435 94 +685 364 528 287 289 +686 212 221 205 240 +687 134 172 149 354 +688 134 172 354 184 +689 319 147 191 307 +690 589 641 606 436 +691 347 79 59 476 +692 345 79 476 92 +693 92 138 144 328 +694 86 92 144 328 +695 32 399 34 38 +696 306 309 336 310 +697 347 604 468 476 +698 347 468 79 476 +699 614 345 79 468 +700 384 310 336 270 +701 439 25 26 422 +702 196 192 314 420 +703 348 420 196 314 +704 132 143 142 318 +705 164 142 143 318 +706 386 406 423 221 +707 35 527 38 40 +708 158 354 96 162 +709 169 302 354 162 +710 334 475 564 363 +711 155 61 303 75 +712 94 353 378 339 +713 224 233 219 212 +714 214 215 204 194 +715 204 243 230 241 +716 204 230 212 241 +717 391 474 369 136 +718 286 588 528 356 +719 35 620 527 47 +720 136 474 361 565 +721 566 526 632 64 +722 490 439 11 14 +723 209 330 420 348 +724 35 527 40 47 +725 76 342 73 98 +726 77 353 102 320 +727 268 308 261 260 +728 167 155 339 378 +729 465 289 385 344 +730 255 308 260 259 +731 335 24 470 33 +732 559 24 470 335 +733 522 1 371 428 +734 347 53 496 54 +735 559 24 607 470 +736 476 347 496 54 +737 312 204 243 307 +738 230 215 243 204 +739 241 218 212 386 +740 241 238 218 386 +741 29 33 28 23 +742 23 335 559 470 +743 297 382 361 341 +744 336 611 185 331 +745 388 185 336 611 +746 353 373 102 320 +747 373 102 314 353 +748 44 527 606 610 +749 74 110 84 353 +750 610 527 606 413 +751 325 341 375 98 +752 369 136 137 391 +753 169 354 342 313 +754 274 366 279 281 +755 281 366 279 276 +756 322 313 206 308 +757 414 289 344 385 +758 114 546 367 434 +759 367 391 434 369 +760 155 163 303 61 +761 47 620 527 44 +762 384 304 552 336 +763 384 310 306 336 +764 99 378 339 94 +765 506 94 378 99 +766 365 353 512 116 +767 378 99 418 506 +768 478 23 559 470 +769 328 86 633 128 +770 265 308 268 266 +771 268 308 263 266 +772 564 419 436 58 +773 460 75 564 65 +774 339 61 99 94 +775 518 564 65 460 +776 643 216 229 392 +777 342 88 76 67 +778 26 422 11 439 +779 26 440 439 571 +780 411 161 373 441 +781 442 467 412 10 +782 350 377 24 33 +783 225 409 217 223 +784 410 377 24 350 +785 24 350 33 335 +786 371 522 523 458 +787 278 324 273 276 +788 273 324 275 276 +789 170 354 172 184 +790 169 179 354 313 +791 607 16 24 580 +792 367 391 137 118 +793 35 620 37 527 +794 548 33 461 333 +795 414 385 344 294 +796 414 289 288 344 +797 65 64 484 454 +798 93 79 78 401 +799 375 382 358 90 +800 413 575 564 594 +801 187 181 368 189 +802 358 375 90 91 +803 275 276 324 323 +804 493 270 323 275 +805 532 323 276 275 +806 324 270 323 415 +807 275 323 324 270 +808 157 331 319 336 +809 454 339 61 338 +810 527 47 507 43 +811 74 87 110 353 +812 61 353 339 155 +813 444 445 618 379 +814 173 133 160 510 +815 352 604 468 347 +816 161 181 373 348 +817 23 335 470 33 +818 181 187 374 373 +819 29 35 28 33 +820 348 187 181 373 +821 562 10 412 447 +822 10 580 503 447 +823 399 351 34 38 +824 515 592 399 32 +825 434 112 637 474 +826 134 82 96 302 +827 224 230 233 212 +828 134 302 96 354 +829 302 354 162 96 +830 376 64 60 564 +831 606 640 589 45 +832 369 137 168 141 +833 113 361 583 136 +834 197 369 168 141 +835 12 7 4 14 +836 510 181 173 171 +837 61 339 353 94 +838 369 154 170 354 +839 404 607 24 21 +840 411 374 578 441 +841 500 186 189 480 +842 535 526 632 566 +843 628 441 497 483 +844 478 23 28 559 +845 28 335 559 23 +846 93 92 78 79 +847 554 473 631 453 +848 198 178 193 141 +849 187 444 209 500 +850 226 388 336 514 +851 287 464 285 528 +852 528 301 285 372 +853 497 629 426 373 +854 394 302 70 82 +855 64 61 454 75 +856 444 587 618 445 +857 467 458 371 523 +858 371 523 520 467 +859 371 520 551 467 +860 385 465 294 292 +861 468 604 345 476 +862 584 517 63 345 +863 176 136 137 369 +864 439 440 18 571 +865 490 26 11 439 +866 324 366 227 357 +867 606 413 419 436 +868 527 48 477 507 +869 527 477 48 457 +870 527 492 48 507 +871 527 626 48 492 +872 134 354 96 158 +873 62 64 489 60 +874 52 57 370 594 +875 326 52 55 564 +876 524 425 17 19 +877 373 441 161 540 +878 373 161 140 540 +879 66 326 55 58 +880 58 326 55 564 +881 310 309 336 270 +882 324 270 336 309 +883 157 336 185 331 +884 181 411 171 161 +885 640 589 641 606 +886 537 557 621 54 +887 282 285 340 288 +888 372 285 288 340 +889 382 100 98 341 +890 502 294 465 292 +891 43 34 351 38 +892 221 240 213 205 +893 438 240 205 213 +894 425 466 524 29 +895 354 302 146 108 +896 435 426 506 629 +897 497 506 426 629 +898 187 181 374 368 +899 517 79 614 345 +900 342 90 73 98 +901 180 141 178 152 +902 178 152 141 168 +903 193 180 141 178 +904 140 161 348 510 +905 9 442 13 362 +906 442 9 13 467 +907 408 505 503 580 +908 607 580 408 16 +909 327 289 414 385 +910 372 284 283 340 +911 359 89 526 566 +912 607 539 478 470 +913 140 373 125 348 +914 328 86 92 517 +915 527 47 44 606 +916 155 163 61 353 +917 367 391 118 434 +918 338 64 61 454 +919 64 338 484 454 +920 359 89 566 338 +921 489 526 566 64 +922 448 192 378 373 +923 350 39 377 33 +924 369 137 176 168 +925 377 350 553 39 +926 325 313 375 341 +927 340 288 625 282 +928 342 313 375 325 +929 524 466 19 20 +930 425 466 19 524 +931 348 395 186 202 +932 610 44 42 45 +933 409 433 217 223 +934 217 433 529 223 +935 582 375 471 115 +936 434 474 637 369 +937 382 375 471 582 +938 98 90 382 375 +939 382 100 90 98 +940 123 105 122 85 +941 122 85 105 80 +942 43 40 34 38 +943 369 474 361 136 +944 469 452 564 460 +945 46 41 527 457 +946 415 366 274 323 +947 191 387 316 438 +948 191 387 156 316 +949 434 391 474 369 +950 502 294 344 465 +951 502 294 292 293 +952 476 59 92 79 +953 306 309 319 336 +954 528 301 464 285 +955 301 282 464 285 +956 208 449 210 379 +957 210 379 220 208 +958 551 520 10 467 +959 359 89 339 106 +960 110 353 365 116 +961 353 511 110 365 +962 118 141 145 152 +963 34 28 466 29 +964 621 347 59 54 +965 59 621 79 347 +966 342 80 122 302 +967 369 123 154 342 +968 123 85 122 342 +969 122 342 85 80 +970 450 349 612 482 +971 564 55 436 413 +972 40 38 29 34 +973 606 641 413 436 +974 28 35 335 33 +975 34 25 32 29 +976 487 548 495 479 +977 187 209 196 348 +978 461 479 430 495 +979 311 513 509 186 +980 395 311 348 186 +981 187 196 209 444 +982 485 540 426 373 +983 21 580 24 447 +984 412 447 21 562 +985 412 562 21 446 +986 447 580 24 10 +987 46 527 610 413 +988 229 392 216 222 +989 323 281 366 274 +990 281 301 274 323 +991 599 625 429 282 +992 608 25 32 34 +993 372 288 284 340 +994 227 324 190 308 +995 373 196 348 187 +996 425 25 34 29 +997 628 448 373 591 +998 591 448 373 398 +999 477 43 41 527 +1000 80 71 81 302 +1001 457 477 41 527 +1002 647 487 430 479 +1003 628 373 497 441 +1004 578 628 441 374 +1005 410 24 335 350 +1006 393 311 160 150 +1007 367 118 137 141 +1008 343 488 356 396 +1009 87 72 61 58 +1010 488 588 356 396 +1011 476 54 59 347 +1012 94 353 61 77 +1013 110 353 87 107 +1014 251 245 322 201 +1015 245 179 322 201 +1016 11 422 486 14 +1017 287 588 464 528 +1018 10 467 412 551 +1019 13 551 412 467 +1020 371 467 551 13 +1021 551 10 8 412 +1022 113 164 361 136 +1023 425 25 15 26 +1024 140 348 125 160 +1025 451 588 528 286 +1026 180 152 145 141 +1027 607 16 539 470 +1028 374 570 400 373 +1029 373 374 556 400 +1030 374 373 556 628 +1031 441 628 578 483 +1032 497 642 418 629 +1033 167 89 106 339 +1034 346 440 390 521 +1035 369 123 342 375 +1036 583 382 498 361 +1037 564 75 72 61 +1038 564 61 64 75 +1039 345 517 79 92 +1040 533 529 223 222 +1041 498 582 576 375 +1042 575 376 609 49 +1043 412 10 8 447 +1044 561 472 549 468 +1045 239 322 252 231 +1046 397 12 4 14 +1047 367 369 434 576 +1048 206 313 322 179 +1049 322 179 313 354 +1050 12 2 4 7 +1051 346 638 26 608 +1052 66 87 57 58 +1053 72 58 564 61 +1054 322 207 231 239 +1055 201 354 322 207 +1056 239 255 322 201 +1057 533 402 529 222 +1058 60 518 564 65 +1059 11 486 12 14 +1060 118 168 141 152 +1061 60 376 564 518 +1062 576 375 582 115 +1063 515 34 399 351 +1064 334 564 64 363 +1065 311 331 150 305 +1066 473 538 597 519 +1067 564 594 575 475 +1068 36 30 432 410 +1069 343 396 356 279 +1070 281 279 356 396 +1071 281 274 301 356 +1072 486 7 14 422 +1073 642 153 585 629 +1074 153 642 628 629 +1075 503 447 8 10 +1076 461 430 620 416 +1077 493 270 275 280 +1078 275 493 532 323 +1079 532 493 282 323 +1080 461 495 430 416 +1081 493 532 280 275 +1082 389 381 47 413 +1083 49 413 626 527 +1084 500 189 186 181 +1085 498 382 582 375 +1086 410 30 24 377 +1087 30 410 36 377 +1088 366 265 279 272 +1089 608 34 32 31 +1090 527 40 43 38 +1091 46 527 41 38 +1092 43 527 38 41 +1093 597 639 7 486 +1094 306 298 336 331 +1095 11 26 15 543 +1096 554 11 15 543 +1097 416 430 620 649 +1098 291 290 364 327 +1099 637 498 375 361 +1100 39 548 33 461 +1101 422 634 25 543 +1102 583 582 382 113 +1103 367 114 118 141 +1104 473 422 11 554 +1105 178 197 168 141 +1106 375 369 123 115 +1107 91 123 115 375 +1108 377 350 36 553 +1109 173 181 516 186 +1110 110 95 107 87 +1111 353 107 163 87 +1112 46 527 42 610 +1113 500 209 348 202 +1114 334 61 564 57 +1115 510 103 140 161 +1116 160 104 140 133 +1117 486 11 473 422 +1118 336 611 331 514 +1119 576 434 637 369 +1120 29 466 524 20 +1121 366 279 265 258 +1122 366 279 258 274 +1123 89 484 338 454 +1124 462 621 568 534 +1125 133 104 140 103 +1126 462 534 568 531 +1127 521 440 390 563 +1128 383 440 563 390 +1129 141 154 170 369 +1130 141 193 369 170 +1131 173 181 510 516 +1132 348 510 181 516 +1133 324 366 276 272 +1134 415 324 366 323 +1135 477 527 507 43 +1136 26 25 440 346 +1137 430 333 42 479 +1138 460 452 564 75 +1139 31 515 32 592 +1140 181 189 187 500 +1141 389 527 413 47 +1142 413 389 626 527 +1143 376 590 49 575 +1144 331 611 185 508 +1145 223 392 407 219 +1146 223 233 392 219 +1147 538 648 597 519 +1148 597 648 538 486 +1149 557 537 568 499 +1150 553 39 461 416 +1151 290 528 451 287 +1152 554 453 332 560 +1153 601 467 458 9 +1154 623 525 535 566 +1155 566 525 535 526 +1156 378 106 431 418 +1157 53 496 352 347 +1158 564 300 419 72 +1159 564 452 300 72 +1160 2 6 7 486 +1161 421 451 528 286 +1162 451 528 588 287 +1163 409 595 433 491 +1164 79 621 78 401 +1165 401 621 78 555 +1166 78 537 555 621 +1167 599 340 282 301 +1168 493 599 282 301 +1169 430 620 42 333 +1170 565 498 112 637 +1171 583 498 112 565 +1172 599 429 536 282 +1173 599 625 459 429 +1174 543 554 332 15 +1175 474 112 637 565 +1176 364 290 528 327 +1177 548 461 479 333 +1178 461 333 430 479 +1179 383 390 346 440 +1180 65 60 64 564 +1181 65 64 75 564 +1182 383 638 346 390 +1183 380 468 614 549 +1184 532 282 276 323 +1185 157 331 504 150 +1186 89 454 338 339 +1187 167 454 89 339 +1188 8 5 10 551 +1189 5 520 10 551 +1190 492 626 545 389 +1191 389 626 545 469 +1192 37 33 35 29 +1193 615 568 499 557 +1194 500 186 480 202 +1195 54 56 53 496 +1196 294 295 291 385 +1197 295 291 385 327 +1198 295 294 292 385 +1199 474 637 361 565 +1200 497 373 426 540 +1201 40 29 28 34 +1202 535 525 581 526 +1203 328 92 79 517 +1204 496 56 352 604 +1205 459 536 646 493 +1206 459 429 624 536 +1207 493 536 280 532 +1208 25 346 26 608 +1209 351 399 41 38 +1210 43 41 38 351 +1211 527 413 47 606 +1212 308 252 322 231 +1213 308 255 322 252 +1214 256 231 252 308 +1215 256 308 259 247 +1216 21 30 24 410 +1217 21 30 562 24 +1218 315 621 555 568 +1219 217 219 223 407 +1220 225 223 219 233 +1221 407 217 529 223 +1222 381 452 300 564 +1223 595 635 433 491 +1224 414 385 291 327 +1225 416 39 461 495 +1226 461 39 548 495 +1227 461 548 479 495 +1228 301 282 281 464 +1229 301 282 285 340 +1230 315 621 568 462 +1231 372 289 288 285 +1232 289 288 285 414 +1233 431 153 106 378 +1234 55 641 589 436 +1235 651 572 638 608 +1236 564 452 72 75 +1237 573 534 567 613 +1238 567 645 600 534 +1239 499 568 577 537 +1240 414 327 291 364 +1241 561 549 614 468 +1242 338 489 566 64 +1243 89 484 489 338 +1244 385 294 465 344 +1245 445 196 444 209 +1246 209 550 444 427 +1247 490 14 11 12 +1248 490 18 14 12 +1249 597 648 486 7 +1250 486 639 7 422 +1251 639 473 597 631 +1252 529 491 616 533 +1253 435 320 125 373 +1254 616 491 529 541 +1255 497 628 642 629 +1256 46 52 413 602 +1257 623 359 566 338 +1258 497 506 629 418 +1259 99 359 623 338 +1260 65 64 454 75 +1261 209 617 550 427 +1262 86 328 144 128 +1263 570 187 374 368 +1264 403 86 633 328 +1265 601 522 458 523 +1266 604 352 472 56 +1267 273 312 319 324 +1268 380 614 63 549 +1269 561 549 63 614 +1270 623 525 566 359 +1271 359 525 566 526 +1272 566 89 526 489 +1273 113 382 358 471 +1274 582 471 382 113 +1275 523 467 458 601 +1276 268 308 260 263 +1277 374 628 556 578 +1278 498 582 382 583 +1279 586 645 534 557 +1280 361 176 369 136 +1281 277 356 274 279 +1282 576 637 375 369 +1283 637 375 369 361 +1284 373 556 569 400 +1285 556 373 569 628 +1286 447 562 24 21 +1287 47 492 527 507 +1288 495 39 548 487 +1289 572 608 651 650 +1290 541 619 542 574 +1291 27 562 21 30 +1292 21 446 562 27 +1293 517 328 614 79 +1294 545 530 622 575 +1295 522 371 523 558 +1296 523 371 520 558 +1297 471 91 115 375 +1298 578 127 628 556 +1299 127 153 628 556 +1300 641 413 55 52 +1301 55 564 436 58 +1302 564 334 57 594 +1303 55 641 436 413 +1304 575 413 49 594 +1305 15 17 596 560 +1306 521 440 563 571 +1307 632 581 62 526 +1308 285 372 301 340 +1309 290 451 528 421 +1310 326 57 564 58 +1311 205 212 241 204 +1312 564 452 469 381 +1313 239 322 207 201 +1314 223 392 529 407 +1315 381 564 413 469 +1316 395 513 311 186 +1317 389 469 413 626 +1318 136 361 583 565 +1319 586 645 567 534 +1320 32 25 608 346 +1321 369 367 137 141 +1322 469 575 545 622 +1323 593 543 634 422 +1324 373 569 628 591 +1325 556 569 153 628 +1326 196 187 373 570 +1327 167 454 339 155 +1328 590 626 575 530 +1329 536 493 282 532 +1330 133 140 160 510 +1331 376 363 64 564 +1332 209 427 444 587 +1333 571 440 563 383 +1334 498 375 576 637 +1335 531 534 568 579 +1336 534 568 557 621 +1337 218 392 643 238 +1338 568 555 577 537 +1339 475 609 363 49 +1340 363 609 475 564 +1341 393 311 150 305 +1342 19 425 17 596 +1343 596 17 603 560 +1344 522 428 371 558 +1345 127 628 497 483 +1346 492 48 545 626 +1347 21 607 24 580 +1348 132 117 318 128 +1349 633 132 547 142 +1350 437 381 419 413 +1351 419 381 437 300 +1352 173 181 186 171 +1353 405 613 600 534 +1354 632 526 62 64 +1355 489 484 64 338 +1356 600 54 53 621 +1357 29 20 28 466 +1358 20 28 466 443 +1359 49 48 626 590 +1360 63 345 614 380 +1361 584 345 63 380 +1362 470 607 559 478 +1363 28 23 22 20 +1364 478 23 22 28 +1365 473 422 554 631 +1366 555 537 568 621 +1367 18 490 14 439 +1368 596 17 19 603 +1369 571 440 18 521 +1370 542 491 616 541 +1371 534 568 615 557 +1372 534 568 579 615 +1373 392 222 229 238 +1374 626 48 530 590 +1375 238 406 229 423 +1376 629 585 642 418 +1377 418 506 629 378 +1378 378 431 629 418 +1379 153 448 628 591 +1380 591 569 628 153 +1381 550 209 500 627 +1382 515 31 32 34 +1383 209 627 550 617 +1384 569 556 153 400 +1385 645 621 557 54 +1386 529 491 533 223 +1387 601 1 458 522 +1388 522 601 1 3 +1389 359 339 99 106 +1390 338 99 359 339 +1391 49 575 626 413 +1392 473 597 631 453 +1393 605 564 518 460 +1394 222 392 402 529 +1395 113 382 583 361 +1396 33 335 28 23 +1397 370 52 594 46 +1398 408 505 580 607 +1399 413 640 602 641 +1400 630 376 564 609 +1401 49 376 609 363 +1402 363 376 609 564 +1403 393 456 311 305 +1404 218 221 386 643 +1405 643 386 423 221 +1406 141 123 369 367 +1407 498 382 375 361 +1408 474 637 369 361 +1409 558 371 520 551 +1410 558 428 371 551 +1411 374 441 411 373 +1412 422 25 26 543 +1413 25 17 15 634 +1414 606 44 610 45 +1415 367 115 369 576 +1416 367 576 546 115 +1417 636 573 567 613 +1418 615 51 579 573 +1419 50 51 615 636 +1420 55 413 564 52 +1421 594 52 413 46 +1422 564 326 52 57 +1423 367 434 546 576 +1424 208 449 379 445 +1425 379 445 544 208 +1426 26 439 440 25 +1427 622 575 605 469 +1428 636 586 567 573 +1429 573 586 567 534 +1430 599 625 340 283 +1431 605 630 518 564 +1432 171 510 181 161 +1433 32 29 38 34 +1434 402 216 392 222 +1435 223 222 392 238 +1436 389 492 527 47 +1437 389 492 626 527 +1438 577 555 78 537 +1439 315 621 401 555 +1440 15 598 634 560 +1441 634 17 15 560 +1442 481 142 328 633 +1443 128 328 144 138 +1444 413 610 640 606 +1445 640 606 610 45 +1446 379 449 444 445 +1447 187 449 196 444 +1448 445 449 444 196 +1449 605 564 460 469 +1450 575 564 605 469 +1451 541 200 619 574 +1452 564 436 419 413 +1453 517 482 63 614 +1454 154 369 141 123 +1455 583 498 565 361 +1456 498 361 637 565 +1457 622 530 630 575 +1458 21 30 432 27 +1459 173 510 160 516 +1460 311 160 348 516 +1461 485 140 540 373 +1462 21 505 580 447 +1463 490 26 439 571 +1464 379 544 220 208 +1465 348 516 181 186 +1466 186 509 311 516 +1467 209 202 627 617 +1468 433 635 529 491 +1469 430 42 620 44 +1470 649 430 620 44 +1471 529 635 541 491 +1472 404 24 410 21 +1473 404 410 24 335 +1474 89 338 359 339 +1475 450 328 482 517 +1476 517 328 482 614 +1477 78 59 537 621 +1478 588 396 281 356 +1479 286 488 588 356 +1480 424 543 593 422 +1481 463 607 408 16 +1482 389 381 413 469 +1483 413 469 575 626 +1484 626 469 575 545 +1485 554 11 543 422 +1486 459 624 646 536 +1487 332 543 593 424 +1488 631 554 424 422 +1489 153 431 629 378 +1490 545 48 530 626 +1491 626 530 545 575 +1492 59 621 78 79 +1493 160 510 348 516 +1494 626 590 575 49 +1495 576 434 112 637 +1496 498 576 112 637 +1497 346 651 638 608 +1498 13 442 412 362 +1499 13 467 412 442 +1500 132 142 633 128 +1501 184 180 172 170 +1502 631 332 424 554 +1503 531 573 579 51 +1504 521 571 563 18 +1505 599 625 282 340 +1506 622 630 605 575 +1507 562 442 362 412 +1508 193 180 170 141 +1509 50 644 636 615 +1510 443 466 20 19 +1511 616 542 533 491 +1512 413 594 564 52 +1513 621 53 600 405 +1514 362 562 446 27 +1515 403 547 321 481 +1516 403 481 321 329 +1517 562 442 412 10 +1518 493 459 536 599 +1519 493 599 536 282 +1520 450 86 328 517 +1521 413 602 610 46 +1522 29 23 28 20 +1523 223 409 433 491 +1524 621 59 537 54 +1525 13 362 412 446 +1526 439 422 11 14 +1527 639 473 631 422 +1528 450 612 584 517 +1529 450 482 612 517 +1530 413 641 602 52 +1531 447 10 24 562 +1532 531 573 534 579 +1533 380 345 468 604 +1534 587 427 444 618 +1535 613 567 600 534 +1536 218 386 238 643 +1537 643 238 423 386 +1538 347 496 352 604 +1539 63 345 517 614 +1540 584 612 63 517 +1541 629 431 585 418 +1542 153 431 585 629 +1543 463 539 478 607 +1544 463 539 607 16 +1545 564 609 475 575 +1546 533 529 402 616 +1547 376 630 564 518 +1548 645 54 600 621 +1549 380 468 472 604 +1550 604 468 472 352 +1551 380 468 549 472 +1552 570 187 373 374 +1553 606 413 641 640 +1554 413 610 602 640 +1555 458 467 13 9 +1556 467 458 13 371 +1557 11 422 26 543 +1558 25 17 425 15 +1559 646 536 280 493 +1560 646 624 280 536 +1561 647 430 44 42 +1562 618 544 220 379 +1563 648 6 486 7 +1564 648 6 538 486 +1565 403 633 547 481 +1566 403 328 633 481 +1567 483 127 628 578 +1568 486 7 12 14 +1569 53 56 352 496 +1570 340 288 284 625 +1571 283 340 284 625 +1572 561 352 472 468 +1573 86 450 328 403 +1574 329 403 481 328 +1575 455 288 284 372 +1576 501 288 284 455 +1577 376 530 575 630 +1578 630 376 609 575 +1579 430 479 42 647 +1580 621 405 600 534 +1581 22 28 20 443 +1582 643 238 229 423 +1583 481 633 547 142 +1584 558 428 551 652 +1585 509 611 331 508 +1586 513 514 331 611 +1587 509 513 331 611 +1588 601 9 1 3 +1589 289 288 344 501 +1590 515 32 399 34 +1591 403 321 349 329 +1592 392 229 643 238 +1593 618 445 544 379 +1594 618 587 544 445 +1595 531 613 534 573 +1596 629 153 448 628 +1597 538 473 597 486 +1598 597 473 639 486 +1599 650 31 608 346 +1600 607 505 580 21 +1601 288 455 289 372 +1602 289 455 288 501 +1603 376 530 590 575 +1604 49 594 475 575 +1605 356 279 281 274 +1606 550 209 444 500 +1607 362 412 446 562 +1608 529 433 491 223 +1609 455 372 284 283 +1610 465 501 455 289 +1611 465 289 344 501 +1612 445 209 444 587 +1613 153 642 127 628 +1614 294 385 291 414 +1615 283 625 459 599 +1616 613 531 51 573 +1617 636 573 613 51 +1618 557 621 568 537 +1619 558 551 520 5 +1620 500 209 202 627 +1621 635 200 541 574 +1622 595 200 635 574 +1623 558 652 551 5 +1624 534 579 573 615 +1625 605 575 630 564 +1626 31 346 32 608 +1627 631 424 639 422 +1628 383 346 638 26 +1629 469 575 564 413 +1630 15 560 332 598 +1631 15 554 332 560 +1632 586 557 534 615 +1633 573 586 534 615 +1634 332 543 598 593 +1635 543 332 598 15 +1636 609 575 564 630 +1637 554 631 332 453 +1638 424 554 543 422 +1639 608 346 651 650 +1640 487 495 430 479 +1641 645 621 534 557 +1642 645 621 600 534 +1643 542 491 541 574 +1644 541 635 574 491 +1645 636 644 586 573 +1646 573 586 615 644 +1647 543 634 598 593 +1648 497 127 642 628 +1649 598 543 15 634 +1650 25 15 543 634 +1651 473 519 597 453 +1652 595 574 635 491 +1653 636 51 615 573 +1654 644 573 636 615 +$EndElements diff --git a/test/user/testdata/shark_41_ascii_missing_node_header.msh b/test/user/testdata/shark_41_ascii_missing_node_header.msh new file mode 100644 index 00000000..55b864c8 --- /dev/null +++ b/test/user/testdata/shark_41_ascii_missing_node_header.msh @@ -0,0 +1,2972 @@ +$MeshFormat +4.1 0 8 +$EndMeshFormat +$Entities +0 0 0 1 +0 -0.07334360000000001 -0.08523339999999999 -0.0005566629999999989 0.07028570000000001 0.0819076 0.0752128 0 0 +$EndEntities +$Nodes + +3 0 0 652 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +-0.07291259999999999 0.0537921 0.00170478 +-0.072634 0.0799069 0.0578949 +-0.0715817 0.0520377 0.00292576 +-0.0701949 0.08025690000000001 0.0450431 +-0.06876980000000001 0.060971 0.00326551 +-0.06778000000000001 0.060358 0.00473741 +-0.06727959999999999 0.08092489999999999 0.0425553 +-0.0658074 0.0806443 0.0552302 +-0.064933 0.0788176 0.0453762 +-0.0636555 0.0610198 0.00141989 +-0.0636111 0.0566004 -0.000556663 +-0.0636791 0.0819076 0.0524468 +-0.0623445 0.0580268 0.00335683 +-0.0624856 0.06710579999999999 0.00581638 +-0.0601398 0.0781111 0.0317589 +-0.0599443 0.0685632 0.009924489999999999 +-0.0592787 0.0571239 0.00105116 +-0.0587906 0.07199990000000001 0.0117948 +-0.0575605 0.0730663 0.016213 +-0.057624 0.0811803 0.0403639 +-0.0572339 0.0769387 0.0223219 +-0.0559974 0.0749629 0.0235691 +-0.0542321 0.0763209 0.0344665 +-0.0540672 0.0649483 0.008218130000000001 +-0.0541685 0.06611350000000001 0.00437935 +-0.0532966 0.0805356 0.0466758 +-0.0517252 0.07611850000000001 0.0183218 +-0.0505257 0.06887699999999999 0.0152572 +-0.0503803 0.07726379999999999 0.0406423 +-0.0472855 0.0641041 0.00381053 +-0.0469016 0.0648796 0.00821733 +-0.0474599 0.07272679999999999 0.0265623 +-0.0464733 0.070912 0.0103373 +-0.0444756 0.07556740000000001 0.0221683 +-0.0440208 0.07743129999999999 0.0371107 +-0.0434135 0.0685101 0.0213943 +-0.0425401 0.0668787 0.0159114 +-0.0405353 0.07301630000000001 0.0309862 +-0.0386417 0.073548 0.0160682 +-0.037401 0.0664899 0.0122191 +-0.0358693 0.06894450000000001 0.0243885 +-0.0351058 0.06877709999999999 0.0124837 +-0.0333614 0.07116500000000001 0.0238503 +-0.0325564 0.0696271 0.024504 +-0.032455 0.0625178 0.0200737 +-0.0305469 0.0729973 0.0173921 +-0.0276941 0.06523859999999999 0.0128238 +-0.0272717 0.0628782 0.0141328 +-0.0263428 0.00735496 0.00505748 +-0.0256055 0.00658056 0.00327552 +-0.0252856 0.0610141 0.0227762 +-0.0250237 -0.00678856 0.00359213 +-0.0242889 -0.00589458 0.00589675 +-0.0216872 0.0639735 0.0255561 +-0.0215721 -0.0119744 0.00619585 +-0.0195136 0.0542304 0.0216195 +-0.0168343 0.06495339999999999 0.0236547 +-0.0161373 -0.00420129 0.00881529 +-0.0148726 0.0585475 0.0106707 +-0.0140647 0.0517836 0.0159197 +-0.0142986 0.0543801 0.0051496 +-0.0139611 -0.0178642 0.00651265 +-0.0139803 0.0554055 0.0115694 +-0.0124373 0.0606817 0.0122622 +-0.0127423 0.0580719 0.0285553 +-0.0127412 -0.07042320000000001 0.0234664 +-0.0126173 -0.0801905 0.022154 +-0.0125269 0.0592002 0.0346418 +-0.0122498 -0.080596 0.0191154 +-0.0121442 -0.0691943 0.0191352 +-0.0123618 0.0658492 0.0197519 +-0.0121018 -0.063334 0.0245151 +-0.0118539 0.0462485 0.0243954 +-0.0111067 0.0637388 0.0161162 +-0.0110042 -0.0624802 0.0276395 +-0.0109072 0.046219 0.0183571 +-0.0107037 -0.000325242 0.00950432 +-0.010183 -0.0121386 0.00674337 +-0.009774420000000001 -0.0638147 0.0162637 +-0.0097669 -0.06993340000000001 0.0156591 +-0.00942656 -0.0836042 0.0182705 +-0.009320999999999999 -0.0852334 0.0216727 +-0.00803502 0.0401179 0.0263407 +-0.00857808 -0.0579335 0.0163943 +-0.007931580000000001 -0.0190616 0.0121625 +-0.00782675 0.0573514 0.028038 +-0.00773028 -0.0620746 0.0302044 +-0.00764665 0.0537773 0.00961295 +-0.00721562 -0.0507362 0.0224357 +-0.00717408 -0.0528249 0.0179333 +-0.00651588 -0.00739691 0.013024 +-0.00691116 -0.00014073 0.00823716 +-0.00661131 0.044183 0.0123 +-0.00658663 0.0535365 0.0326225 +-0.00630954 -0.08506569999999999 0.0194796 +-0.00616497 -0.0797841 0.0261073 +-0.00582999 -0.0494502 0.0287705 +-0.00563359 0.0476479 0.00934546 +-0.00506609 -0.0425596 0.0250833 +-0.00453974 -0.0405694 0.0173853 +-0.00447266 0.0319291 0.0205877 +-0.00434886 0.0267225 0.00648417 +-0.00418386 0.0253438 0.008421959999999999 +-0.0041733 -0.0606038 0.0122716 +-0.00385183 0.0479538 0.00869149 +-0.00333705 0.051389 0.031593 +-0.00333565 -0.06938809999999999 0.0119551 +-0.00333748 -0.0650683 0.0110291 +-0.00292457 0.0475597 0.0319288 +-0.00280471 -0.0353375 0.0238411 +-0.00273019 -0.0493159 0.0135756 +-0.00255346 -0.0452657 0.0126112 +-0.00249178 -0.0598565 0.010934 +-0.00247351 -0.0533955 0.0149632 +-0.00280465 0.0288144 0.0300227 +-0.00225175 -0.030519 0.0236922 +-0.00205777 -0.0595101 0.00715068 +-0.0018581 -0.0627033 0.0116048 +-0.00150112 -0.0384203 0.0313885 +-0.00143547 -0.0337232 0.0176227 +-0.00136747 -0.062725 0.0150152 +-0.000884775 -0.0587825 0.0143119 +-0.000624659 -0.0247814 0.0257906 +-0.000489974 0.0225414 0.0188523 +-6.05566e-05 0.0171338 0.0234086 +0.00150381 0.0360475 0.00675461 +0.000282178 -0.0241462 0.0174969 +0.000347869 -0.06752370000000001 0.0324883 +0.000429839 -0.0422219 0.0349169 +0.00028168 -0.0273698 0.0312235 +0.000952705 -0.0267391 0.0143612 +0.00105244 0.0186951 0.00689988 +0.0011109 -0.0779453 0.014663 +0.00137887 0.00842564 0.0258445 +0.00107238 -0.0462225 0.00980545 +0.00158113 -0.0561697 0.005809 +0.00165921 -0.0142314 0.0114909 +0.00169065 -0.00330978 0.027848 +0.0017282 0.0264299 0.00972258 +0.00196109 -0.062067 0.0125082 +0.00198494 -0.0249792 0.0122768 +0.00206797 -0.0322322 0.0125632 +0.00219287 -0.00991015 0.0199027 +0.00223228 -0.065619 0.00972103 +0.00226787 -0.06664 0.0139131 +0.00233081 0.009707510000000001 0.0349608 +0.0023033 -0.0550711 0.0357611 +0.00284591 -0.06958739999999999 0.0109337 +0.00313658 0.0123831 0.0152878 +0.00325266 -0.000639164 0.0164744 +0.00354678 -0.0651674 0.00553443 +0.00434877 0.0392681 0.00656793 +0.0034004 -0.0624097 0.0143354 +0.00410027 0.052311 0.0146156 +0.00425687 -0.0110681 0.0377954 +0.0043501 -0.0020508 0.015115 +0.00444422 -0.0785667 0.0168482 +0.00471578 -0.008727459999999999 0.0133588 +0.00486541 0.0192794 0.0102326 +0.00475235 0.0259901 0.00777948 +0.00497525 -0.0797755 0.0244877 +0.0052286 0.0545416 0.0234287 +0.00513856 -0.0361953 0.00904286 +0.00543656 -0.016404 0.0117933 +0.00521097 0.0361763 0.0357574 +0.00563068 0.0458779 0.0101474 +0.00602624 -0.0598053 0.00448538 +0.00669265 -0.0730234 0.0300997 +0.00671975 -0.0647944 0.0149968 +0.00743572 0.0219428 0.00498754 +0.00806977 -0.06766220000000001 0.0106835 +0.008580020000000001 0.0185363 0.00804532 +0.00900922 -0.0527441 0.0382868 +0.00967438 -0.0310472 0.0412759 +0.009690270000000001 -0.0470756 0.00574739 +0.009825469999999999 -0.0777201 0.0238208 +0.010337 -0.0646559 0.00738197 +0.0103691 -0.0715108 0.0301524 +0.0108524 -0.06519229999999999 0.0107074 +0.0112352 0.0223598 0.00496048 +0.0115762 0.0360388 0.034027 +0.011811 0.0150563 0.0411225 +0.0119389 -0.07108730000000001 0.0142927 +0.011481 0.000850754 0.00890493 +0.0122581 0.0177891 0.00726338 +0.0126044 0.0285097 0.0071727 +0.0126077 -0.0410848 0.00487059 +0.01325 0.0245576 0.00385279 +0.0133342 -0.0301914 0.00695184 +0.0134526 -0.00467313 0.044297 +0.0140263 0.0415073 0.0128325 +0.0139319 -0.0627506 0.0126489 +0.0144402 0.0213321 0.0408733 +0.0145153 -0.0120242 0.00709154 +0.0145254 0.0314471 0.00762861 +0.0143606 -0.0539791 0.00638859 +0.0153705 -0.0588177 0.00913193 +0.0158483 0.0424843 0.0267153 +0.0161677 0.0082135 0.0752128 +0.0160709 -0.0693691 0.0267104 +0.0163112 0.021127 0.00658374 +0.0163956 0.0418119 0.0180916 +0.0166653 0.00513625 0.0449469 +0.0171438 -0.009394380000000001 0.0462661 +0.0174416 -0.0497054 0.0373642 +0.0174198 -0.06569369999999999 0.0159871 +0.0177387 0.0346114 0.0053358 +0.0178439 0.0247259 0.00729322 +0.018247 0.0346901 0.00258831 +0.0182074 -0.0318958 0.0424624 +0.0183988 -0.00142899 0.0496692 +0.0188182 -0.018825 0.0447569 +0.0188285 0.0147456 0.0461032 +0.0188626 0.015416 0.041072 +0.0190811 -0.00419709 0.06868580000000001 +0.0195945 0.0084326 0.064095 +0.0197498 -0.00217441 0.0583864 +0.0198208 0.00539755 0.0587622 +0.0200137 0.0324539 0.00354185 +0.020151 -0.0145671 0.0500049 +0.0203386 -0.00326709 0.07024469999999999 +0.0209148 0.00523036 0.0681576 +0.0208447 0.0121045 0.0546374 +0.0209724 0.009706330000000001 0.0633876 +0.020604 -0.0121123 0.00591309 +0.0212498 -0.0289526 0.00565549 +0.0216078 -0.0380775 0.00479088 +0.0216875 -0.00997672 0.0619769 +0.0220658 0.00705093 0.0456869 +0.0223002 -0.0558455 0.0110476 +0.0223137 -0.0154618 0.0494217 +0.0229336 0.00417573 0.0589573 +0.0231427 0.0278288 0.0125965 +0.0231751 0.027241 0.0309726 +0.0233259 0.0160686 0.00756079 +0.0234095 0.0318943 0.0199392 +0.0234462 -0.00393483 0.0583985 +0.0235915 -0.0597066 0.0170609 +0.0240196 -0.0108777 0.0466362 +0.024123 -0.00330273 0.0464733 +0.0242099 -0.0321428 0.0398591 +0.0244244 0.00347947 0.0416421 +0.024564 -0.0175604 0.0433407 +0.0253979 -0.0453083 0.0344803 +0.0256103 0.0267734 0.0284514 +0.0259312 -0.0445208 0.00878379 +0.025959 -0.0133125 0.00624018 +0.0265967 -0.0369666 0.00635268 +0.0273245 -0.0066598 0.0412078 +0.0277597 -0.0467651 0.0304517 +0.0275944 -0.0515878 0.0207552 +0.0282687 0.0208205 0.0174814 +0.0290859 0.0112094 0.012597 +0.0293048 -0.0474855 0.0256026 +0.0296506 -0.0466043 0.0156453 +0.0304236 0.0134394 0.031696 +0.0304518 -0.0291908 0.00746031 +0.03126 -0.044124 0.016095 +0.0321715 -0.043346 0.0242104 +0.0322352 -0.0402733 0.0141242 +0.0323149 0.01052 0.0200521 +0.0324768 -0.0397188 0.0271188 +0.0325431 -0.0291932 0.0340382 +0.0332479 -0.0329826 0.0117351 +0.0338676 -0.0346121 0.0252676 +0.0341522 -0.00293196 0.033596 +0.0341882 -0.0361716 0.0179088 +0.0344969 -0.0256263 0.0309923 +0.0345138 -0.00958586 0.0123416 +0.0348872 -0.0128566 0.0339912 +0.0349524 -0.0273994 0.0177976 +0.0349556 -0.000677158 0.0209767 +0.0350004 -0.028049 0.008761420000000001 +0.0353194 -0.0100316 0.0154749 +0.0354214 -0.0195455 0.0173172 +0.0355775 -0.0309821 0.0107592 +0.0360305 -0.0150581 0.0232372 +0.0363938 -0.0285041 0.0132933 +0.0374738 -0.00607371 0.0123945 +0.041317 -0.0210454 0.0131228 +0.0425886 -0.0120136 0.0129537 +0.0475164 -0.00753527 0.00853843 +0.0492593 -0.00704914 0.009380670000000001 +0.0496752 -0.0170405 0.0106038 +0.0498676 -0.0259318 0.00619626 +0.052402 -0.022331 0.00866719 +0.0516897 -0.011391 0.0103437 +0.0559595 -0.0106346 0.00698866 +0.0596531 -0.0214295 0.0059579 +0.066312 -0.0158462 0.00759335 +0.0672852 -0.00331292 0.00667068 +0.0687074 -0.0027598 0.00829441 +0.0687083 -0.008451500000000001 0.00881385 +0.07028570000000001 -0.00694567 0.00665748 +0.02471 0.00101921 0.00688758 +0.00641783 -0.0341512 0.0233596 +0.024018 0.00854392 0.00722419 +0.0251696 0.009421270000000001 0.00784613 +-0.019815 0.0686939 0.0189821 +0.0416697 -0.017118 0.00864259 +-0.00440288 -0.06984319999999999 0.0205811 +-0.0033606 0.0600219 0.0217676 +0.0268544 0.00322876 0.008082499999999999 +0.00855449 0.0107052 0.00928038 +0.0219179 0.00585482 0.0121236 +0.0199208 0.0175811 0.0336776 +0.0210521 -0.0362113 0.0256186 +0.0339797 -0.00194129 0.0163861 +0.03202 0.000337126 0.0126992 +0.0119633 0.0163586 0.0147908 +0.0248778 0.0056119 0.0321775 +0.00892971 -0.0563678 0.0287948 +0.0174837 0.027107 0.0210333 +-0.0170518 0.00346089 0.00554363 +0.0144974 -0.0120686 0.0314959 +0.00336155 -0.00103205 0.0364574 +0.00707711 -0.0204903 0.0185209 +0.010517 -0.00309481 0.0232445 +-0.00559352 0.0373259 0.0172753 +-0.00523735 -0.0230725 0.0111224 +0.0151072 -0.0538804 0.0213778 +0.0347571 -0.0188174 0.0105515 +0.0278657 -0.0183642 0.0156758 +-0.00338013 -0.0543805 0.0329679 +-0.0196332 0.0593213 0.0251138 +0.06481629999999999 -0.0143432 0.00627944 +-0.00336175 -0.0187472 0.00979996 +-0.0059938 -0.0214388 0.00941436 +0.0204933 0.0262773 0.00994486 +0.0153554 0.00838654 0.0105168 +-0.064082 0.064994 0.00682263 +-0.0406296 0.0703091 0.0249838 +-0.0197677 0.0563929 0.0156108 +-0.0506931 0.0781816 0.0304629 +0.0171972 -0.00100568 0.011485 +0.0314619 -0.0225976 0.00774901 +-0.00980694 0.0515267 0.0104574 +-0.00435185 0.0493969 0.0137744 +0.0449063 -0.0117353 0.00859937 +0.00159087 -0.0450385 0.027858 +-0.00469537 -0.06372510000000001 0.0233918 +0.0424219 -0.0285632 0.00857374 +0.0603894 -0.00835109 0.009350529999999999 +-0.0147113 -0.0156046 0.009183759999999999 +-0.0528157 0.0611754 0.00480955 +-0.0173765 -0.008871489999999999 0.00520522 +0.0108104 0.02268 0.0130558 +-0.00899905 -0.0208443 0.00915416 +-0.0449914 0.0768094 0.0302276 +-0.0408502 0.06658 0.008368489999999999 +-0.0199988 -0.0118916 0.004906 +0.00337131 0.0455887 0.0238561 +0.00477413 -0.0721541 0.0211645 +-0.00344193 -0.049333 0.032475 +0.0427245 -0.0268877 0.00738607 +0.0272704 -0.0238375 0.00669928 +-0.00610544 -0.0476638 0.0181008 +-0.00760153 0.0503529 0.00747858 +0.0131109 -0.0422224 0.0405109 +0.00214561 -0.0490294 0.0151357 +-0.0598224 0.0805424 0.0511855 +-0.0204542 0.0588165 0.013102 +0.059357 -0.0190886 0.00813027 +-0.00100716 0.0422264 0.0325724 +0.0325535 -0.0244764 0.012522 +-0.000431427 -0.0574818 0.0137747 +0.0114251 0.0275734 0.00440942 +0.00337666 -0.0559724 0.0148659 +-0.0262911 0.0586227 0.0207785 +-0.0699467 0.0813567 0.0499003 +0.0494602 -0.0133111 0.00757754 +0.00758285 0.0333008 0.0104911 +0.00657287 0.032122 0.00603963 +0.000332803 -0.0511328 0.0180756 +-0.021764 0.0620607 0.0118108 +-0.0454672 0.075167 0.035911 +0.00139884 0.045926 0.0128133 +0.0176314 0.0311493 0.00370344 +-0.0159418 -0.0158578 0.00793814 +-0.0229387 0.06916410000000001 0.0166572 +-0.00133409 -0.0449329 0.0187829 +-0.0538019 0.0611146 0.00198764 +0.0305208 -0.00256491 0.0101919 +0.0623596 -0.00697151 0.00683979 +0.0236819 -0.00777996 0.0526871 +0.0118138 -0.0144241 0.0430193 +0.0137156 -0.00365078 0.00732253 +-0.0257884 0.0686739 0.0150694 +-0.0530331 0.060812 0.00248197 +-0.000421194 -0.0523335 0.008791770000000001 +0.0193846 -0.00072024 0.0649221 +0.00485856 0.0133946 0.0114741 +-0.0053823 -0.0743714 0.0141262 +0.016958 0.0166471 0.00740593 +0.0429338 -0.0266961 0.0110582 +-0.06504749999999999 0.05473 0.00191127 +0.00924818 0.0356698 0.00715588 +-0.042468 0.0652669 0.00790867 +0.00699205 0.0348997 0.00576165 +-0.012123 0.00171435 0.00688121 +0.017741 0.00126373 0.0717161 +-0.00477874 -0.0228765 0.0123522 +-0.05496 0.0793832 0.0329037 +-0.0253736 -0.000654191 0.00342534 +0.0220159 -0.0128389 0.0555838 +0.0187915 0.00366305 0.06539010000000001 +-0.0635923 0.0794618 0.0351284 +0.0187293 0.00901455 0.0689246 +-0.0507436 0.0790633 0.0364811 +0.00440962 0.0291856 0.00589534 +-0.0610541 0.08157639999999999 0.0467801 +-0.0264169 0.06418980000000001 0.0180225 +0.0590681 -0.0129818 0.009692930000000001 +0.0316732 -0.013669 0.008927310000000001 +-0.0368828 0.0732351 0.028231 +0.0147007 -0.0293577 0.0425282 +-0.00226105 0.042112 0.008184220000000001 +-0.022404 0.068624 0.0211714 +0.018834 0.0296379 0.0101126 +0.0545664 -0.023882 0.00596013 +-0.0610274 0.0626039 0.00623226 +0.0209345 -0.0123916 0.0558755 +-0.064258 0.0639612 0.00701622 +-0.0530259 0.07099660000000001 0.0104874 +-0.000350232 0.0328643 0.009503569999999999 +0.0179821 0.0260225 0.00525665 +-0.071629 0.0809096 0.0500374 +0.0431333 -0.00662611 0.0109755 +-0.0367738 0.072104 0.0272887 +-0.00147996 0.0424733 0.00778004 +-0.0489442 0.0792518 0.0424775 +0.0178184 0.008309230000000001 0.0698262 +-0.00256208 -0.0518644 0.0119693 +-0.0024457 0.0347988 0.0115191 +-0.0226391 0.067054 0.0236986 +-0.0250562 0.070839 0.0181046 +0.0157661 -0.010775 0.0444953 +-0.0587069 0.0610686 0.00549325 +-0.0561989 0.0607157 0.00436391 +0.0028322 0.0311045 0.0076099 +-0.061857 0.079748 0.0514834 +-0.0580072 0.07448539999999999 0.0170926 +0.017366 0.0281829 0.00449304 +0.0175246 0.0303053 0.00632184 +-0.0583716 0.0812348 0.0494755 +-0.06276379999999999 0.08110589999999999 0.0418948 +0.009583370000000001 0.0391723 0.00889538 +0.0164997 0.0327763 0.00400793 +-0.0100537 -0.019407 0.0104569 +0.0535082 -0.023589 0.00757618 +-0.0184567 0.0672393 0.0165986 +-0.0660887 0.06395149999999999 0.00557639 +-0.008500499999999999 0.0591911 0.0132991 +0.0527123 -0.00658592 0.00801901 +0.00664445 0.0147496 0.00979726 +-0.0323364 0.06468409999999999 0.013176 +-0.06849810000000001 0.0817682 0.0541475 +0.0424951 -0.00680449 0.0104665 +-0.01583 0.06382989999999999 0.0140017 +-0.0408586 0.07478079999999999 0.0276312 +-0.0213675 0.00505684 0.00440033 +-0.0609542 0.0784149 0.029815 +0.0458286 -0.0196104 0.0115924 +0.0619857 -0.0044448 0.00717137 +-0.0549453 0.0736446 0.0144159 +-0.0660739 0.0797747 0.0511232 +-0.0150243 -0.0138696 0.00597473 +-0.0208919 0.06642729999999999 0.014553 +-0.0583912 0.07667309999999999 0.0277458 +-0.00499489 -0.0492059 0.0154875 +-0.0177596 -0.0149926 0.00640227 +-0.0656257 0.0638276 0.00437301 +-0.00111824 -0.0505712 0.010634 +-0.0234714 0.0595273 0.0150887 +-0.0117477 -0.00786715 0.0107629 +-0.0329423 0.0662408 0.012525 +-0.0588644 0.0778049 0.0265316 +-0.038272 0.07101209999999999 0.0277124 +0.0147178 0.0228905 0.00513556 +-0.00242697 -0.0228032 0.0106496 +-0.00998317 -0.0196685 0.00798312 +0.00194711 0.0338412 0.00734265 +-0.0101071 0.0571173 0.0108272 +-0.000192036 0.0305177 0.010316 +-0.06622359999999999 0.0609953 0.00234663 +-0.0383437 0.071981 0.0290737 +0.0464353 -0.0271448 0.00729223 +-0.0113654 0.0558876 0.00985606 +-0.0600686 0.0581853 0.00037707 +0.0184892 0.00651809 0.072001 +-0.0272353 0.0661385 0.0125002 +0.0386787 -0.009397559999999999 0.0110365 +-0.00702298 -0.0554164 0.0301677 +-0.0387296 0.0725599 0.0291973 +-0.0195884 -0.009713039999999999 0.00731553 +0.0009803979999999999 0.0340005 0.008311529999999999 +-0.00251349 -0.0493306 0.0137872 +-0.0208118 0.00468072 0.00662791 +0.0145465 0.0247675 0.00685396 +0.0539643 -0.00601143 0.00911787 +0.0615879 -0.00432066 0.00875869 +-0.0649217 0.0800024 0.0383643 +0.00460493 0.008497380000000001 0.0127005 +-0.0606311 0.0803611 0.0379233 +-0.00316884 0.0400824 0.00969248 +-0.0308482 0.067467 0.0126012 +0.0120049 0.00511369 0.00824306 +0.0117314 0.0134932 0.00784586 +0.0067401 0.0222359 0.00786688 +0.000365941 0.0444987 0.0334101 +0.00589042 0.0427357 0.0325284 +0.0134556 0.013691 0.0071386 +0.0155774 0.00572549 0.00675779 +-0.0442054 0.0654197 0.00607699 +0.00863004 0.0184766 0.00878081 +-0.0111016 -0.0170398 0.0107756 +-0.0162643 0.06208 0.0123266 +-0.06706429999999999 0.0628756 0.0047451 +-0.0673064 0.07917689999999999 0.0489333 +-0.0566743 0.0588231 0.00264455 +-0.07138410000000001 0.080001 0.0523997 +-0.0690781 0.0794039 0.0521145 +-0.0589744 0.07029879999999999 0.0123753 +-0.0108026 0.05228 0.00636676 +-0.0113486 0.0541547 0.00728553 +-0.0299136 0.06862409999999999 0.0165753 +0.0505332 -0.0225927 0.00635398 +0.0180077 0.0031318 0.07043870000000001 +-0.0235313 0.0640143 0.012641 +-0.0235569 0.00584404 0.00381922 +0.0384718 -0.0113423 0.0144484 +0.0182407 0.00232532 0.0728388 +-0.0235752 0.00407866 0.00373027 +-0.011585 0.0522432 0.00647843 +0.0400312 -0.00904366 0.0126741 +-0.0178591 -0.000359808 0.00797485 +-0.067167 0.06255139999999999 0.00392853 +-0.0596438 0.0779391 0.0290601 +0.0013543 0.0302152 0.00901705 +0.0168301 0.00522322 0.0737244 +0.0174324 0.00448014 0.0738384 +-0.0618546 0.0649931 0.00590465 +0.0194429 0.0304209 0.00452872 +-0.0236633 0.0648084 0.0124456 +-0.00249493 -0.0562542 0.012985 +-0.0025263 -0.0246783 0.0125409 +-0.0396392 0.0718092 0.02876 +-0.0158083 -0.0164708 0.00645267 +0.016879 0.0245859 0.0055459 +-0.06884990000000001 0.0811361 0.0461884 +0.0290982 -0.00647478 0.008279069999999999 +-0.041817 0.0761358 0.0343691 +-0.0642688 0.0653922 0.00517065 +-0.0162175 0.00239503 0.00694561 +0.00467524 0.0360758 0.00643588 +-0.0222973 0.0035638 0.00646752 +-0.0708092 0.0801688 0.0482801 +-0.0549524 0.07870829999999999 0.0296023 +-0.06310540000000001 0.0672415 0.00811831 +-0.0155444 -0.0163359 0.0060847 +-0.0574097 0.07880470000000001 0.0473507 +-0.0558952 0.0591814 0.001764 +-0.0177409 0.0619627 0.0144786 +-0.00178349 -0.0487397 0.0125937 +-0.0111058 0.0522074 0.008299040000000001 +-0.0260139 0.00360897 0.00461987 +-0.0204566 0.00423454 0.00564674 +0.00612936 0.0370467 0.00680554 +0.010446 0.0313554 0.00705031 +-0.0569353 0.05965 0.00118235 +-0.0506685 0.0625792 0.00279292 +-0.0249761 0.00485573 0.00443819 +0.0172421 0.00725128 0.07382619999999999 +-0.0219613 0.06430039999999999 0.0138184 +-0.00260185 -0.0513557 0.0142694 +-0.0167422 0.00259292 0.00779623 +0.00214524 0.0341103 0.00650831 +-0.0236765 0.00572293 0.004305 +-0.0616879 0.0784644 0.0353636 +-0.0125522 0.0533024 0.00573952 +-0.00373263 -0.048886 0.014509 +-0.00253347 -0.0472982 0.0131992 +-0.0128746 -0.017623 0.00940414 +-5.43548e-05 0.0393803 0.00728201 +-0.0258702 0.00405717 0.00525282 +0.0183599 0.0265636 0.00640112 +0.0459896 -0.0257989 0.0100883 +-0.0295424 0.06805940000000001 0.0247957 +-0.0245383 0.0634107 0.0123732 +0.0066096 0.0377811 0.00691952 +-0.0450015 0.0646553 0.00575343 +-0.0622505 0.0661482 0.00839783 +-0.0256248 0.0608105 0.0161665 +0.017488 0.00853314 0.07209649999999999 +-0.0596734 0.07050969999999999 0.009924850000000001 +-0.06657979999999999 0.06286890000000001 0.00493615 +-0.0624322 0.0664941 0.0080812 +0.0436037 -0.00911409 0.009504510000000001 +-0.0258241 0.00183578 0.00455937 +-0.07027029999999999 0.07969130000000001 0.0546337 +-0.027947 0.06304949999999999 0.0231884 +-0.0601839 0.07046330000000001 0.0106076 +-0.019796 -0.0130118 0.0069497 +-0.0183149 0.06305479999999999 0.012418 +-0.0302535 0.0701272 0.02364 +-0.0574291 0.07908510000000001 0.0314511 +-0.0506885 0.0650762 0.00396145 +-0.021101 0.0616869 0.0137094 +-0.0331684 0.0670427 0.023997 +0.0134393 0.00644533 0.00718965 +-0.0111807 -0.0194906 0.00818236 +-0.0255718 0.00304117 0.00332801 +-0.0126697 -0.015488 0.00653208 +-0.0247074 0.00660999 0.00551935 +0.0173416 0.0031807 0.0727906 +0.0172416 0.0236783 0.00588169 +0.0190309 0.0293428 0.00437137 +0.016715 0.00646681 0.0747173 +-0.0362286 0.072292 0.023504 +-0.0193589 -0.00042516 0.00470745 +-0.0218861 0.06436310000000001 0.0125137 +-0.0102557 0.0512168 0.00711881 +0.0404202 -0.00631757 0.0116411 +0.0462272 -0.00679819 0.0101561 +-0.0259792 0.0656558 0.0150971 +0.0162732 0.0229634 0.00624384 +0.00353474 0.0364474 0.008433390000000001 +4.6368e-06 0.0388726 0.009730829999999999 +-0.0216501 0.0633078 0.012475 +-0.06535530000000001 0.0635995 0.0060088 +-0.0129397 0.0533345 0.00604151 +-0.00189413 -0.0244631 0.013557 +-0.0610974 0.0673557 0.00916116 +0.0169636 0.00823874 0.0726305 +-0.0262169 0.00566462 0.00486021 +-0.00105663 -0.050339 0.013034 +-0.0522352 0.0618469 0.00239028 +-0.06586110000000001 0.0623674 0.00600767 +-0.0308719 0.0671807 0.0240148 +-0.0271033 0.0631674 0.0232081 +0.000463176 0.0377435 0.00713404 +0.0197653 -0.0105149 0.0573133 +-0.0261272 0.00574879 0.00514751 +-0.0256133 0.00236555 0.00535812 +0.0395658 -0.00664927 0.0115095 +-0.0346515 0.0704144 0.0260764 +-0.0676857 0.0619198 0.00410476 +-0.0352382 0.07226829999999999 0.0261851 +-0.0489272 0.0632235 0.00329626 +-0.0514659 0.0617489 0.00295197 +-0.070483 0.0805389 0.0464472 +$EndNodes +$Elements +1 1654 1 1654 +3 0 4 1654 +1 26 15 543 25 +2 227 308 190 188 +3 203 353 199 163 +4 331 305 504 150 +5 142 328 128 138 +6 490 439 18 571 +7 364 289 287 414 +8 296 336 304 298 +9 564 419 300 381 +10 398 569 373 591 +11 486 473 639 422 +12 338 89 566 489 +13 332 554 543 424 +14 80 67 71 302 +15 149 146 109 108 +16 98 90 375 342 +17 341 308 325 313 +18 147 314 126 116 +19 124 318 156 131 +20 245 322 206 308 +21 348 311 516 186 +22 135 150 319 151 +23 147 314 307 311 +24 464 588 301 528 +25 461 33 35 333 +26 196 192 373 314 +27 108 81 302 122 +28 366 258 227 357 +29 511 107 512 353 +30 146 170 354 172 +31 297 175 156 130 +32 130 297 175 308 +33 318 159 319 195 +34 154 123 122 342 +35 261 308 259 260 +36 132 142 128 318 +37 241 250 240 205 +38 226 227 248 324 +39 575 609 475 49 +40 375 91 123 90 +41 260 308 255 251 +42 517 612 63 482 +43 120 117 131 297 +44 318 131 297 156 +45 147 319 311 307 +46 131 120 297 130 +47 120 297 111 117 +48 308 174 206 360 +49 148 313 325 175 +50 148 313 175 174 +51 302 80 122 81 +52 107 353 511 110 +53 322 231 198 197 +54 61 58 564 57 +55 240 386 212 221 +56 121 297 143 117 +57 121 297 117 111 +58 307 235 314 182 +59 307 314 166 182 +60 417 308 175 316 +61 308 175 360 417 +62 601 9 458 1 +63 459 429 536 599 +64 211 242 206 308 +65 528 588 301 356 +66 316 297 308 175 +67 197 188 308 228 +68 231 308 228 197 +69 231 197 322 308 +70 188 197 308 361 +71 322 361 308 197 +72 259 308 256 255 +73 298 306 304 299 +74 302 342 146 122 +75 251 322 245 308 +76 298 306 299 236 +77 342 302 169 129 +78 157 319 331 150 +79 190 195 324 227 +80 146 342 354 154 +81 190 297 308 324 +82 236 254 306 299 +83 354 179 201 322 +84 308 297 188 361 +85 361 188 164 297 +86 195 165 190 318 +87 307 215 257 235 +88 194 235 215 307 +89 174 129 148 313 +90 169 313 129 174 +91 322 255 251 201 +92 366 265 308 258 +93 227 308 258 366 +94 258 308 249 265 +95 227 308 228 258 +96 448 192 373 196 +97 228 308 249 258 +98 296 298 514 336 +99 125 150 348 126 +100 125 160 348 150 +101 244 264 242 316 +102 264 316 244 271 +103 224 233 225 219 +104 107 353 163 199 +105 217 223 219 225 +106 308 174 313 206 +107 206 313 179 174 +108 241 230 212 233 +109 241 233 212 218 +110 267 278 312 273 +111 267 312 262 273 +112 206 179 322 245 +113 242 245 206 308 +114 144 319 159 157 +115 265 308 266 272 +116 218 219 392 233 +117 264 324 316 271 +118 324 308 264 316 +119 297 318 117 131 +120 128 117 318 124 +121 354 207 201 177 +122 207 177 354 184 +123 155 163 353 203 +124 131 297 156 130 +125 395 330 236 202 +126 164 142 318 190 +127 253 314 234 311 +128 307 314 147 166 +129 331 234 253 254 +130 306 236 298 331 +131 156 297 316 175 +132 324 319 318 316 +133 297 324 316 308 +134 373 314 102 125 +135 167 155 378 192 +136 278 324 272 269 +137 278 276 272 324 +138 319 159 157 336 +139 267 257 312 243 +140 307 215 243 257 +141 156 297 318 316 +142 207 354 170 184 +143 124 144 139 156 +144 267 312 250 243 +145 144 151 139 319 +146 318 316 319 144 +147 316 139 319 144 +148 139 144 316 156 +149 316 191 312 319 +150 316 191 317 156 +151 313 308 175 174 +152 253 234 331 311 +153 331 395 234 236 +154 272 265 308 366 +155 103 140 133 510 +156 235 199 246 314 +157 246 237 314 199 +158 144 151 319 157 +159 92 157 151 144 +160 92 159 157 144 +161 395 234 236 330 +162 395 330 202 348 +163 348 330 202 209 +164 324 312 316 271 +165 266 308 324 272 +166 324 366 308 227 +167 242 264 245 308 +168 272 266 269 324 +169 135 151 319 139 +170 40 35 28 29 +171 88 148 129 342 +172 325 342 148 88 +173 314 116 147 166 +174 77 353 320 94 +175 331 262 319 306 +176 319 317 139 316 +177 450 329 482 328 +178 183 307 147 166 +179 188 361 176 197 +180 169 179 313 174 +181 314 196 348 373 +182 102 84 116 353 +183 102 77 84 353 +184 191 147 319 317 +185 307 262 257 312 +186 307 257 246 235 +187 307 257 262 246 +188 128 318 144 124 +189 246 314 237 253 +190 314 203 237 234 +191 142 128 318 138 +192 253 237 234 314 +193 306 319 331 336 +194 307 314 235 246 +195 316 250 312 191 +196 450 403 349 329 +197 121 297 101 143 +198 382 164 101 297 +199 369 198 322 193 +200 264 266 324 269 +201 322 354 170 207 +202 322 170 193 207 +203 353 84 116 110 +204 70 302 68 83 +205 331 311 234 395 +206 323 493 282 301 +207 269 278 324 271 +208 278 312 324 271 +209 207 170 180 184 +210 207 170 193 180 +211 325 130 175 308 +212 146 354 170 154 +213 354 302 342 146 +214 161 348 510 181 +215 182 314 199 235 +216 322 354 369 170 +217 231 207 322 198 +218 313 322 375 341 +219 375 361 341 322 +220 322 207 193 198 +221 297 143 164 101 +222 221 213 240 232 +223 190 188 308 297 +224 341 361 375 382 +225 341 308 313 322 +226 134 158 184 354 +227 247 308 261 249 +228 263 308 260 251 +229 318 319 159 144 +230 309 262 306 319 +231 250 204 243 312 +232 448 192 167 378 +233 37 333 620 35 +234 37 33 333 35 +235 297 318 316 324 +236 167 448 378 153 +237 212 218 233 219 +238 88 325 342 494 +239 246 307 314 253 +240 307 253 246 262 +241 126 311 150 348 +242 388 611 336 514 +243 348 234 420 314 +244 236 254 331 306 +245 348 314 311 234 +246 211 308 360 417 +247 373 102 320 125 +248 316 250 191 438 +249 250 205 191 438 +250 254 262 306 309 +251 254 309 306 310 +252 299 254 306 310 +253 331 262 306 254 +254 292 294 295 293 +255 194 307 215 204 +256 304 306 384 299 +257 267 312 257 262 +258 353 192 378 155 +259 319 159 336 195 +260 353 192 373 378 +261 336 185 388 195 +262 312 250 271 267 +263 271 250 312 316 +264 261 249 308 265 +265 268 308 265 261 +266 247 308 249 228 +267 227 195 324 226 +268 366 324 415 337 +269 337 366 324 357 +270 190 195 318 324 +271 156 318 124 144 +272 263 266 308 264 +273 251 263 308 264 +274 197 198 322 369 +275 154 354 369 342 +276 188 308 228 227 +277 79 328 138 92 +278 316 317 139 156 +279 360 175 308 174 +280 255 251 308 322 +281 255 256 252 308 +282 247 228 231 308 +283 247 308 231 256 +284 134 149 394 354 +285 83 162 96 302 +286 161 373 140 348 +287 88 67 302 68 +288 302 97 88 68 +289 512 166 314 182 +290 420 192 314 234 +291 348 330 420 234 +292 192 314 234 203 +293 91 123 105 115 +294 394 70 302 81 +295 309 273 262 319 +296 319 262 312 273 +297 67 302 68 70 +298 271 278 312 267 +299 66 57 326 58 +300 188 136 176 361 +301 157 331 185 504 +302 136 361 188 164 +303 244 250 271 316 +304 71 302 67 70 +305 244 213 232 240 +306 81 302 71 70 +307 354 149 108 146 +308 314 237 203 199 +309 506 378 435 629 +310 244 438 316 213 +311 97 302 169 162 +312 244 316 438 250 +313 313 129 342 169 +314 382 113 101 164 +315 506 435 378 94 +316 91 123 85 105 +317 308 264 245 251 +318 242 264 308 316 +319 450 349 482 329 +320 314 373 348 125 +321 92 138 159 144 +322 395 311 234 348 +323 278 273 324 312 +324 373 378 435 320 +325 147 311 319 135 +326 126 311 135 150 +327 126 135 311 147 +328 314 348 311 126 +329 83 302 82 70 +330 378 435 629 373 +331 195 159 165 318 +332 316 312 324 319 +333 156 175 316 387 +334 336 298 514 331 +335 88 342 129 302 +336 319 307 331 311 +337 253 314 311 307 +338 311 331 253 307 +339 297 341 308 130 +340 314 348 126 125 +341 147 314 311 126 +342 61 339 99 338 +343 250 204 312 191 +344 305 185 508 331 +345 211 242 308 316 +346 211 308 417 316 +347 213 316 211 417 +348 214 215 230 204 +349 244 316 242 211 +350 244 211 213 316 +351 465 501 344 502 +352 108 354 302 394 +353 313 129 148 342 +354 337 324 415 248 +355 337 258 366 357 +356 121 101 297 111 +357 382 101 111 297 +358 157 159 185 336 +359 226 336 195 324 +360 307 262 331 253 +361 307 262 319 331 +362 331 254 253 262 +363 248 336 552 296 +364 319 324 195 336 +365 248 296 226 336 +366 324 248 336 552 +367 147 183 191 307 +368 282 281 276 323 +369 281 323 282 301 +370 109 119 105 122 +371 297 143 117 318 +372 109 122 105 80 +373 308 366 324 272 +374 297 318 324 190 +375 297 190 164 318 +376 214 204 230 212 +377 224 212 214 230 +378 297 143 318 164 +379 264 308 324 266 +380 264 269 324 271 +381 132 117 143 318 +382 130 297 341 120 +383 341 130 120 98 +384 277 343 356 279 +385 325 308 175 313 +386 109 81 108 122 +387 109 122 108 146 +388 348 234 395 330 +389 341 111 120 297 +390 341 100 98 120 +391 341 111 100 120 +392 226 336 324 248 +393 318 319 324 195 +394 275 270 324 309 +395 309 336 324 319 +396 552 270 336 324 +397 273 309 275 324 +398 403 328 329 450 +399 382 111 341 297 +400 361 322 308 341 +401 361 341 308 297 +402 342 85 73 90 +403 342 73 85 80 +404 323 324 366 276 +405 361 297 164 382 +406 96 82 83 302 +407 45 647 44 42 +408 179 354 201 177 +409 53 621 54 347 +410 117 124 131 318 +411 156 144 316 318 +412 369 198 193 141 +413 342 302 88 67 +414 67 80 342 302 +415 73 80 342 67 +416 342 73 67 76 +417 372 528 289 285 +418 285 528 289 287 +419 355 98 325 494 +420 122 119 105 123 +421 394 82 134 302 +422 494 88 76 342 +423 109 81 122 80 +424 447 580 503 505 +425 114 118 141 145 +426 311 150 319 135 +427 108 122 302 146 +428 204 307 183 194 +429 191 204 307 183 +430 382 101 100 111 +431 382 111 100 341 +432 318 159 138 144 +433 588 281 301 356 +434 87 61 77 57 +435 318 159 165 138 +436 7 12 2 486 +437 316 191 319 317 +438 208 196 449 445 +439 322 369 354 313 +440 354 158 177 162 +441 354 169 162 179 +442 313 369 354 342 +443 179 162 354 177 +444 130 98 341 355 +445 325 130 341 355 +446 337 357 324 248 +447 324 357 227 248 +448 588 281 464 301 +449 375 341 382 98 +450 454 75 61 155 +451 353 77 84 74 +452 331 305 185 504 +453 311 331 319 150 +454 378 339 167 106 +455 318 190 142 165 +456 138 142 165 318 +457 18 12 397 14 +458 298 514 331 513 +459 118 137 141 168 +460 298 331 236 395 +461 395 298 331 513 +462 93 157 92 159 +463 354 158 184 177 +464 151 157 92 93 +465 78 93 151 92 +466 378 448 629 153 +467 102 314 126 125 +468 126 116 314 102 +469 61 72 303 75 +470 39 461 350 553 +471 350 39 33 461 +472 311 331 513 395 +473 311 331 305 509 +474 353 102 314 116 +475 204 215 243 307 +476 106 153 167 378 +477 97 162 83 302 +478 107 353 199 512 +479 297 188 164 190 +480 147 319 139 135 +481 77 353 87 74 +482 353 203 199 314 +483 512 314 353 199 +484 37 38 29 35 +485 485 140 373 125 +486 398 448 373 196 +487 196 570 373 398 +488 324 248 552 415 +489 415 270 552 324 +490 52 57 594 564 +491 285 289 414 287 +492 438 250 205 240 +493 524 425 25 17 +494 29 25 524 425 +495 87 77 61 353 +496 93 92 138 159 +497 93 92 79 138 +498 203 192 353 155 +499 192 353 314 203 +500 88 302 129 97 +501 169 342 354 302 +502 147 319 317 139 +503 435 426 629 373 +504 197 168 369 176 +505 369 176 361 197 +506 157 151 319 150 +507 307 319 312 191 +508 312 307 191 204 +509 628 373 441 374 +510 513 331 311 509 +511 49 594 413 46 +512 303 163 87 61 +513 146 342 154 122 +514 274 366 415 337 +515 274 258 366 337 +516 87 57 74 66 +517 304 306 336 384 +518 204 250 205 191 +519 110 74 66 87 +520 163 87 61 353 +521 204 205 250 241 +522 387 438 213 316 +523 150 160 348 311 +524 313 369 342 375 +525 313 322 369 375 +526 97 129 169 302 +527 504 305 393 150 +528 181 348 500 187 +529 610 527 42 44 +530 44 527 42 620 +531 311 305 456 509 +532 311 509 456 516 +533 365 512 166 116 +534 116 512 166 314 +535 509 305 508 331 +536 322 369 193 170 +537 535 526 581 632 +538 182 314 512 199 +539 497 441 373 540 +540 37 42 46 527 +541 500 209 187 348 +542 312 257 307 243 +543 323 366 281 276 +544 348 420 209 196 +545 366 279 276 272 +546 202 500 186 348 +547 386 406 221 232 +548 64 526 62 489 +549 336 159 185 195 +550 404 24 559 335 +551 404 24 607 559 +552 384 336 552 270 +553 244 240 438 213 +554 244 438 240 250 +555 430 461 620 333 +556 461 333 35 620 +557 61 564 64 334 +558 381 437 47 413 +559 279 277 265 258 +560 279 277 258 274 +561 186 500 181 348 +562 140 510 348 160 +563 377 410 36 350 +564 202 330 236 209 +565 380 345 614 468 +566 99 339 378 106 +567 378 106 418 99 +568 378 448 373 629 +569 194 235 307 182 +570 194 307 166 182 +571 194 307 183 166 +572 353 373 320 378 +573 68 97 83 302 +574 347 496 604 476 +575 161 181 411 373 +576 570 374 400 368 +577 40 38 35 29 +578 364 289 327 528 +579 324 309 319 273 +580 353 378 320 94 +581 358 91 471 375 +582 134 394 302 354 +583 394 149 108 354 +584 172 354 146 149 +585 382 358 471 375 +586 101 382 90 358 +587 651 346 638 390 +588 382 90 100 101 +589 334 594 564 475 +590 369 361 375 322 +591 322 197 369 361 +592 342 325 98 494 +593 325 313 148 342 +594 342 325 375 98 +595 115 369 123 367 +596 342 98 76 494 +597 369 375 576 115 +598 353 512 116 314 +599 336 304 552 296 +600 336 306 304 298 +601 226 514 336 296 +602 108 302 81 394 +603 181 411 373 374 +604 26 440 571 383 +605 26 383 346 440 +606 211 360 308 206 +607 87 74 57 77 +608 358 113 101 382 +609 195 388 336 226 +610 241 233 218 238 +611 155 339 378 353 +612 345 79 468 476 +613 213 316 417 175 +614 387 316 213 175 +615 312 307 262 319 +616 435 485 426 373 +617 435 373 125 485 +618 299 310 306 384 +619 26 425 25 34 +620 118 114 367 434 +621 26 34 25 608 +622 223 222 529 392 +623 527 38 37 35 +624 37 527 46 38 +625 342 123 90 375 +626 342 123 85 90 +627 335 350 33 35 +628 350 461 33 35 +629 85 91 90 123 +630 259 247 308 261 +631 629 628 448 373 +632 633 142 328 128 +633 629 497 628 373 +634 303 61 87 72 +635 236 254 234 331 +636 341 98 325 355 +637 373 570 400 569 +638 398 570 373 569 +639 49 413 527 46 +640 49 46 527 457 +641 49 626 48 527 +642 241 204 243 250 +643 49 527 48 457 +644 392 218 233 238 +645 233 392 238 223 +646 178 198 197 141 +647 198 197 141 369 +648 364 290 287 528 +649 419 381 564 413 +650 92 78 79 59 +651 192 373 314 353 +652 386 406 238 423 +653 367 369 137 391 +654 437 413 419 606 +655 413 437 47 606 +656 239 252 322 255 +657 454 61 339 155 +658 34 466 425 29 +659 221 386 232 240 +660 60 64 489 484 +661 484 65 60 64 +662 212 386 218 221 +663 241 240 386 212 +664 241 205 240 212 +665 607 24 16 470 +666 620 42 37 527 +667 37 333 42 620 +668 95 87 66 69 +669 113 164 382 361 +670 410 30 432 21 +671 371 1 522 458 +672 527 47 43 40 +673 596 425 17 15 +674 393 456 160 311 +675 110 95 87 66 +676 160 311 456 516 +677 512 511 365 166 +678 353 511 365 512 +679 128 144 318 138 +680 341 130 325 308 +681 87 61 57 58 +682 419 58 564 72 +683 414 289 327 364 +684 320 378 435 94 +685 364 528 287 289 +686 212 221 205 240 +687 134 172 149 354 +688 134 172 354 184 +689 319 147 191 307 +690 589 641 606 436 +691 347 79 59 476 +692 345 79 476 92 +693 92 138 144 328 +694 86 92 144 328 +695 32 399 34 38 +696 306 309 336 310 +697 347 604 468 476 +698 347 468 79 476 +699 614 345 79 468 +700 384 310 336 270 +701 439 25 26 422 +702 196 192 314 420 +703 348 420 196 314 +704 132 143 142 318 +705 164 142 143 318 +706 386 406 423 221 +707 35 527 38 40 +708 158 354 96 162 +709 169 302 354 162 +710 334 475 564 363 +711 155 61 303 75 +712 94 353 378 339 +713 224 233 219 212 +714 214 215 204 194 +715 204 243 230 241 +716 204 230 212 241 +717 391 474 369 136 +718 286 588 528 356 +719 35 620 527 47 +720 136 474 361 565 +721 566 526 632 64 +722 490 439 11 14 +723 209 330 420 348 +724 35 527 40 47 +725 76 342 73 98 +726 77 353 102 320 +727 268 308 261 260 +728 167 155 339 378 +729 465 289 385 344 +730 255 308 260 259 +731 335 24 470 33 +732 559 24 470 335 +733 522 1 371 428 +734 347 53 496 54 +735 559 24 607 470 +736 476 347 496 54 +737 312 204 243 307 +738 230 215 243 204 +739 241 218 212 386 +740 241 238 218 386 +741 29 33 28 23 +742 23 335 559 470 +743 297 382 361 341 +744 336 611 185 331 +745 388 185 336 611 +746 353 373 102 320 +747 373 102 314 353 +748 44 527 606 610 +749 74 110 84 353 +750 610 527 606 413 +751 325 341 375 98 +752 369 136 137 391 +753 169 354 342 313 +754 274 366 279 281 +755 281 366 279 276 +756 322 313 206 308 +757 414 289 344 385 +758 114 546 367 434 +759 367 391 434 369 +760 155 163 303 61 +761 47 620 527 44 +762 384 304 552 336 +763 384 310 306 336 +764 99 378 339 94 +765 506 94 378 99 +766 365 353 512 116 +767 378 99 418 506 +768 478 23 559 470 +769 328 86 633 128 +770 265 308 268 266 +771 268 308 263 266 +772 564 419 436 58 +773 460 75 564 65 +774 339 61 99 94 +775 518 564 65 460 +776 643 216 229 392 +777 342 88 76 67 +778 26 422 11 439 +779 26 440 439 571 +780 411 161 373 441 +781 442 467 412 10 +782 350 377 24 33 +783 225 409 217 223 +784 410 377 24 350 +785 24 350 33 335 +786 371 522 523 458 +787 278 324 273 276 +788 273 324 275 276 +789 170 354 172 184 +790 169 179 354 313 +791 607 16 24 580 +792 367 391 137 118 +793 35 620 37 527 +794 548 33 461 333 +795 414 385 344 294 +796 414 289 288 344 +797 65 64 484 454 +798 93 79 78 401 +799 375 382 358 90 +800 413 575 564 594 +801 187 181 368 189 +802 358 375 90 91 +803 275 276 324 323 +804 493 270 323 275 +805 532 323 276 275 +806 324 270 323 415 +807 275 323 324 270 +808 157 331 319 336 +809 454 339 61 338 +810 527 47 507 43 +811 74 87 110 353 +812 61 353 339 155 +813 444 445 618 379 +814 173 133 160 510 +815 352 604 468 347 +816 161 181 373 348 +817 23 335 470 33 +818 181 187 374 373 +819 29 35 28 33 +820 348 187 181 373 +821 562 10 412 447 +822 10 580 503 447 +823 399 351 34 38 +824 515 592 399 32 +825 434 112 637 474 +826 134 82 96 302 +827 224 230 233 212 +828 134 302 96 354 +829 302 354 162 96 +830 376 64 60 564 +831 606 640 589 45 +832 369 137 168 141 +833 113 361 583 136 +834 197 369 168 141 +835 12 7 4 14 +836 510 181 173 171 +837 61 339 353 94 +838 369 154 170 354 +839 404 607 24 21 +840 411 374 578 441 +841 500 186 189 480 +842 535 526 632 566 +843 628 441 497 483 +844 478 23 28 559 +845 28 335 559 23 +846 93 92 78 79 +847 554 473 631 453 +848 198 178 193 141 +849 187 444 209 500 +850 226 388 336 514 +851 287 464 285 528 +852 528 301 285 372 +853 497 629 426 373 +854 394 302 70 82 +855 64 61 454 75 +856 444 587 618 445 +857 467 458 371 523 +858 371 523 520 467 +859 371 520 551 467 +860 385 465 294 292 +861 468 604 345 476 +862 584 517 63 345 +863 176 136 137 369 +864 439 440 18 571 +865 490 26 11 439 +866 324 366 227 357 +867 606 413 419 436 +868 527 48 477 507 +869 527 477 48 457 +870 527 492 48 507 +871 527 626 48 492 +872 134 354 96 158 +873 62 64 489 60 +874 52 57 370 594 +875 326 52 55 564 +876 524 425 17 19 +877 373 441 161 540 +878 373 161 140 540 +879 66 326 55 58 +880 58 326 55 564 +881 310 309 336 270 +882 324 270 336 309 +883 157 336 185 331 +884 181 411 171 161 +885 640 589 641 606 +886 537 557 621 54 +887 282 285 340 288 +888 372 285 288 340 +889 382 100 98 341 +890 502 294 465 292 +891 43 34 351 38 +892 221 240 213 205 +893 438 240 205 213 +894 425 466 524 29 +895 354 302 146 108 +896 435 426 506 629 +897 497 506 426 629 +898 187 181 374 368 +899 517 79 614 345 +900 342 90 73 98 +901 180 141 178 152 +902 178 152 141 168 +903 193 180 141 178 +904 140 161 348 510 +905 9 442 13 362 +906 442 9 13 467 +907 408 505 503 580 +908 607 580 408 16 +909 327 289 414 385 +910 372 284 283 340 +911 359 89 526 566 +912 607 539 478 470 +913 140 373 125 348 +914 328 86 92 517 +915 527 47 44 606 +916 155 163 61 353 +917 367 391 118 434 +918 338 64 61 454 +919 64 338 484 454 +920 359 89 566 338 +921 489 526 566 64 +922 448 192 378 373 +923 350 39 377 33 +924 369 137 176 168 +925 377 350 553 39 +926 325 313 375 341 +927 340 288 625 282 +928 342 313 375 325 +929 524 466 19 20 +930 425 466 19 524 +931 348 395 186 202 +932 610 44 42 45 +933 409 433 217 223 +934 217 433 529 223 +935 582 375 471 115 +936 434 474 637 369 +937 382 375 471 582 +938 98 90 382 375 +939 382 100 90 98 +940 123 105 122 85 +941 122 85 105 80 +942 43 40 34 38 +943 369 474 361 136 +944 469 452 564 460 +945 46 41 527 457 +946 415 366 274 323 +947 191 387 316 438 +948 191 387 156 316 +949 434 391 474 369 +950 502 294 344 465 +951 502 294 292 293 +952 476 59 92 79 +953 306 309 319 336 +954 528 301 464 285 +955 301 282 464 285 +956 208 449 210 379 +957 210 379 220 208 +958 551 520 10 467 +959 359 89 339 106 +960 110 353 365 116 +961 353 511 110 365 +962 118 141 145 152 +963 34 28 466 29 +964 621 347 59 54 +965 59 621 79 347 +966 342 80 122 302 +967 369 123 154 342 +968 123 85 122 342 +969 122 342 85 80 +970 450 349 612 482 +971 564 55 436 413 +972 40 38 29 34 +973 606 641 413 436 +974 28 35 335 33 +975 34 25 32 29 +976 487 548 495 479 +977 187 209 196 348 +978 461 479 430 495 +979 311 513 509 186 +980 395 311 348 186 +981 187 196 209 444 +982 485 540 426 373 +983 21 580 24 447 +984 412 447 21 562 +985 412 562 21 446 +986 447 580 24 10 +987 46 527 610 413 +988 229 392 216 222 +989 323 281 366 274 +990 281 301 274 323 +991 599 625 429 282 +992 608 25 32 34 +993 372 288 284 340 +994 227 324 190 308 +995 373 196 348 187 +996 425 25 34 29 +997 628 448 373 591 +998 591 448 373 398 +999 477 43 41 527 +1000 80 71 81 302 +1001 457 477 41 527 +1002 647 487 430 479 +1003 628 373 497 441 +1004 578 628 441 374 +1005 410 24 335 350 +1006 393 311 160 150 +1007 367 118 137 141 +1008 343 488 356 396 +1009 87 72 61 58 +1010 488 588 356 396 +1011 476 54 59 347 +1012 94 353 61 77 +1013 110 353 87 107 +1014 251 245 322 201 +1015 245 179 322 201 +1016 11 422 486 14 +1017 287 588 464 528 +1018 10 467 412 551 +1019 13 551 412 467 +1020 371 467 551 13 +1021 551 10 8 412 +1022 113 164 361 136 +1023 425 25 15 26 +1024 140 348 125 160 +1025 451 588 528 286 +1026 180 152 145 141 +1027 607 16 539 470 +1028 374 570 400 373 +1029 373 374 556 400 +1030 374 373 556 628 +1031 441 628 578 483 +1032 497 642 418 629 +1033 167 89 106 339 +1034 346 440 390 521 +1035 369 123 342 375 +1036 583 382 498 361 +1037 564 75 72 61 +1038 564 61 64 75 +1039 345 517 79 92 +1040 533 529 223 222 +1041 498 582 576 375 +1042 575 376 609 49 +1043 412 10 8 447 +1044 561 472 549 468 +1045 239 322 252 231 +1046 397 12 4 14 +1047 367 369 434 576 +1048 206 313 322 179 +1049 322 179 313 354 +1050 12 2 4 7 +1051 346 638 26 608 +1052 66 87 57 58 +1053 72 58 564 61 +1054 322 207 231 239 +1055 201 354 322 207 +1056 239 255 322 201 +1057 533 402 529 222 +1058 60 518 564 65 +1059 11 486 12 14 +1060 118 168 141 152 +1061 60 376 564 518 +1062 576 375 582 115 +1063 515 34 399 351 +1064 334 564 64 363 +1065 311 331 150 305 +1066 473 538 597 519 +1067 564 594 575 475 +1068 36 30 432 410 +1069 343 396 356 279 +1070 281 279 356 396 +1071 281 274 301 356 +1072 486 7 14 422 +1073 642 153 585 629 +1074 153 642 628 629 +1075 503 447 8 10 +1076 461 430 620 416 +1077 493 270 275 280 +1078 275 493 532 323 +1079 532 493 282 323 +1080 461 495 430 416 +1081 493 532 280 275 +1082 389 381 47 413 +1083 49 413 626 527 +1084 500 189 186 181 +1085 498 382 582 375 +1086 410 30 24 377 +1087 30 410 36 377 +1088 366 265 279 272 +1089 608 34 32 31 +1090 527 40 43 38 +1091 46 527 41 38 +1092 43 527 38 41 +1093 597 639 7 486 +1094 306 298 336 331 +1095 11 26 15 543 +1096 554 11 15 543 +1097 416 430 620 649 +1098 291 290 364 327 +1099 637 498 375 361 +1100 39 548 33 461 +1101 422 634 25 543 +1102 583 582 382 113 +1103 367 114 118 141 +1104 473 422 11 554 +1105 178 197 168 141 +1106 375 369 123 115 +1107 91 123 115 375 +1108 377 350 36 553 +1109 173 181 516 186 +1110 110 95 107 87 +1111 353 107 163 87 +1112 46 527 42 610 +1113 500 209 348 202 +1114 334 61 564 57 +1115 510 103 140 161 +1116 160 104 140 133 +1117 486 11 473 422 +1118 336 611 331 514 +1119 576 434 637 369 +1120 29 466 524 20 +1121 366 279 265 258 +1122 366 279 258 274 +1123 89 484 338 454 +1124 462 621 568 534 +1125 133 104 140 103 +1126 462 534 568 531 +1127 521 440 390 563 +1128 383 440 563 390 +1129 141 154 170 369 +1130 141 193 369 170 +1131 173 181 510 516 +1132 348 510 181 516 +1133 324 366 276 272 +1134 415 324 366 323 +1135 477 527 507 43 +1136 26 25 440 346 +1137 430 333 42 479 +1138 460 452 564 75 +1139 31 515 32 592 +1140 181 189 187 500 +1141 389 527 413 47 +1142 413 389 626 527 +1143 376 590 49 575 +1144 331 611 185 508 +1145 223 392 407 219 +1146 223 233 392 219 +1147 538 648 597 519 +1148 597 648 538 486 +1149 557 537 568 499 +1150 553 39 461 416 +1151 290 528 451 287 +1152 554 453 332 560 +1153 601 467 458 9 +1154 623 525 535 566 +1155 566 525 535 526 +1156 378 106 431 418 +1157 53 496 352 347 +1158 564 300 419 72 +1159 564 452 300 72 +1160 2 6 7 486 +1161 421 451 528 286 +1162 451 528 588 287 +1163 409 595 433 491 +1164 79 621 78 401 +1165 401 621 78 555 +1166 78 537 555 621 +1167 599 340 282 301 +1168 493 599 282 301 +1169 430 620 42 333 +1170 565 498 112 637 +1171 583 498 112 565 +1172 599 429 536 282 +1173 599 625 459 429 +1174 543 554 332 15 +1175 474 112 637 565 +1176 364 290 528 327 +1177 548 461 479 333 +1178 461 333 430 479 +1179 383 390 346 440 +1180 65 60 64 564 +1181 65 64 75 564 +1182 383 638 346 390 +1183 380 468 614 549 +1184 532 282 276 323 +1185 157 331 504 150 +1186 89 454 338 339 +1187 167 454 89 339 +1188 8 5 10 551 +1189 5 520 10 551 +1190 492 626 545 389 +1191 389 626 545 469 +1192 37 33 35 29 +1193 615 568 499 557 +1194 500 186 480 202 +1195 54 56 53 496 +1196 294 295 291 385 +1197 295 291 385 327 +1198 295 294 292 385 +1199 474 637 361 565 +1200 497 373 426 540 +1201 40 29 28 34 +1202 535 525 581 526 +1203 328 92 79 517 +1204 496 56 352 604 +1205 459 536 646 493 +1206 459 429 624 536 +1207 493 536 280 532 +1208 25 346 26 608 +1209 351 399 41 38 +1210 43 41 38 351 +1211 527 413 47 606 +1212 308 252 322 231 +1213 308 255 322 252 +1214 256 231 252 308 +1215 256 308 259 247 +1216 21 30 24 410 +1217 21 30 562 24 +1218 315 621 555 568 +1219 217 219 223 407 +1220 225 223 219 233 +1221 407 217 529 223 +1222 381 452 300 564 +1223 595 635 433 491 +1224 414 385 291 327 +1225 416 39 461 495 +1226 461 39 548 495 +1227 461 548 479 495 +1228 301 282 281 464 +1229 301 282 285 340 +1230 315 621 568 462 +1231 372 289 288 285 +1232 289 288 285 414 +1233 431 153 106 378 +1234 55 641 589 436 +1235 651 572 638 608 +1236 564 452 72 75 +1237 573 534 567 613 +1238 567 645 600 534 +1239 499 568 577 537 +1240 414 327 291 364 +1241 561 549 614 468 +1242 338 489 566 64 +1243 89 484 489 338 +1244 385 294 465 344 +1245 445 196 444 209 +1246 209 550 444 427 +1247 490 14 11 12 +1248 490 18 14 12 +1249 597 648 486 7 +1250 486 639 7 422 +1251 639 473 597 631 +1252 529 491 616 533 +1253 435 320 125 373 +1254 616 491 529 541 +1255 497 628 642 629 +1256 46 52 413 602 +1257 623 359 566 338 +1258 497 506 629 418 +1259 99 359 623 338 +1260 65 64 454 75 +1261 209 617 550 427 +1262 86 328 144 128 +1263 570 187 374 368 +1264 403 86 633 328 +1265 601 522 458 523 +1266 604 352 472 56 +1267 273 312 319 324 +1268 380 614 63 549 +1269 561 549 63 614 +1270 623 525 566 359 +1271 359 525 566 526 +1272 566 89 526 489 +1273 113 382 358 471 +1274 582 471 382 113 +1275 523 467 458 601 +1276 268 308 260 263 +1277 374 628 556 578 +1278 498 582 382 583 +1279 586 645 534 557 +1280 361 176 369 136 +1281 277 356 274 279 +1282 576 637 375 369 +1283 637 375 369 361 +1284 373 556 569 400 +1285 556 373 569 628 +1286 447 562 24 21 +1287 47 492 527 507 +1288 495 39 548 487 +1289 572 608 651 650 +1290 541 619 542 574 +1291 27 562 21 30 +1292 21 446 562 27 +1293 517 328 614 79 +1294 545 530 622 575 +1295 522 371 523 558 +1296 523 371 520 558 +1297 471 91 115 375 +1298 578 127 628 556 +1299 127 153 628 556 +1300 641 413 55 52 +1301 55 564 436 58 +1302 564 334 57 594 +1303 55 641 436 413 +1304 575 413 49 594 +1305 15 17 596 560 +1306 521 440 563 571 +1307 632 581 62 526 +1308 285 372 301 340 +1309 290 451 528 421 +1310 326 57 564 58 +1311 205 212 241 204 +1312 564 452 469 381 +1313 239 322 207 201 +1314 223 392 529 407 +1315 381 564 413 469 +1316 395 513 311 186 +1317 389 469 413 626 +1318 136 361 583 565 +1319 586 645 567 534 +1320 32 25 608 346 +1321 369 367 137 141 +1322 469 575 545 622 +1323 593 543 634 422 +1324 373 569 628 591 +1325 556 569 153 628 +1326 196 187 373 570 +1327 167 454 339 155 +1328 590 626 575 530 +1329 536 493 282 532 +1330 133 140 160 510 +1331 376 363 64 564 +1332 209 427 444 587 +1333 571 440 563 383 +1334 498 375 576 637 +1335 531 534 568 579 +1336 534 568 557 621 +1337 218 392 643 238 +1338 568 555 577 537 +1339 475 609 363 49 +1340 363 609 475 564 +1341 393 311 150 305 +1342 19 425 17 596 +1343 596 17 603 560 +1344 522 428 371 558 +1345 127 628 497 483 +1346 492 48 545 626 +1347 21 607 24 580 +1348 132 117 318 128 +1349 633 132 547 142 +1350 437 381 419 413 +1351 419 381 437 300 +1352 173 181 186 171 +1353 405 613 600 534 +1354 632 526 62 64 +1355 489 484 64 338 +1356 600 54 53 621 +1357 29 20 28 466 +1358 20 28 466 443 +1359 49 48 626 590 +1360 63 345 614 380 +1361 584 345 63 380 +1362 470 607 559 478 +1363 28 23 22 20 +1364 478 23 22 28 +1365 473 422 554 631 +1366 555 537 568 621 +1367 18 490 14 439 +1368 596 17 19 603 +1369 571 440 18 521 +1370 542 491 616 541 +1371 534 568 615 557 +1372 534 568 579 615 +1373 392 222 229 238 +1374 626 48 530 590 +1375 238 406 229 423 +1376 629 585 642 418 +1377 418 506 629 378 +1378 378 431 629 418 +1379 153 448 628 591 +1380 591 569 628 153 +1381 550 209 500 627 +1382 515 31 32 34 +1383 209 627 550 617 +1384 569 556 153 400 +1385 645 621 557 54 +1386 529 491 533 223 +1387 601 1 458 522 +1388 522 601 1 3 +1389 359 339 99 106 +1390 338 99 359 339 +1391 49 575 626 413 +1392 473 597 631 453 +1393 605 564 518 460 +1394 222 392 402 529 +1395 113 382 583 361 +1396 33 335 28 23 +1397 370 52 594 46 +1398 408 505 580 607 +1399 413 640 602 641 +1400 630 376 564 609 +1401 49 376 609 363 +1402 363 376 609 564 +1403 393 456 311 305 +1404 218 221 386 643 +1405 643 386 423 221 +1406 141 123 369 367 +1407 498 382 375 361 +1408 474 637 369 361 +1409 558 371 520 551 +1410 558 428 371 551 +1411 374 441 411 373 +1412 422 25 26 543 +1413 25 17 15 634 +1414 606 44 610 45 +1415 367 115 369 576 +1416 367 576 546 115 +1417 636 573 567 613 +1418 615 51 579 573 +1419 50 51 615 636 +1420 55 413 564 52 +1421 594 52 413 46 +1422 564 326 52 57 +1423 367 434 546 576 +1424 208 449 379 445 +1425 379 445 544 208 +1426 26 439 440 25 +1427 622 575 605 469 +1428 636 586 567 573 +1429 573 586 567 534 +1430 599 625 340 283 +1431 605 630 518 564 +1432 171 510 181 161 +1433 32 29 38 34 +1434 402 216 392 222 +1435 223 222 392 238 +1436 389 492 527 47 +1437 389 492 626 527 +1438 577 555 78 537 +1439 315 621 401 555 +1440 15 598 634 560 +1441 634 17 15 560 +1442 481 142 328 633 +1443 128 328 144 138 +1444 413 610 640 606 +1445 640 606 610 45 +1446 379 449 444 445 +1447 187 449 196 444 +1448 445 449 444 196 +1449 605 564 460 469 +1450 575 564 605 469 +1451 541 200 619 574 +1452 564 436 419 413 +1453 517 482 63 614 +1454 154 369 141 123 +1455 583 498 565 361 +1456 498 361 637 565 +1457 622 530 630 575 +1458 21 30 432 27 +1459 173 510 160 516 +1460 311 160 348 516 +1461 485 140 540 373 +1462 21 505 580 447 +1463 490 26 439 571 +1464 379 544 220 208 +1465 348 516 181 186 +1466 186 509 311 516 +1467 209 202 627 617 +1468 433 635 529 491 +1469 430 42 620 44 +1470 649 430 620 44 +1471 529 635 541 491 +1472 404 24 410 21 +1473 404 410 24 335 +1474 89 338 359 339 +1475 450 328 482 517 +1476 517 328 482 614 +1477 78 59 537 621 +1478 588 396 281 356 +1479 286 488 588 356 +1480 424 543 593 422 +1481 463 607 408 16 +1482 389 381 413 469 +1483 413 469 575 626 +1484 626 469 575 545 +1485 554 11 543 422 +1486 459 624 646 536 +1487 332 543 593 424 +1488 631 554 424 422 +1489 153 431 629 378 +1490 545 48 530 626 +1491 626 530 545 575 +1492 59 621 78 79 +1493 160 510 348 516 +1494 626 590 575 49 +1495 576 434 112 637 +1496 498 576 112 637 +1497 346 651 638 608 +1498 13 442 412 362 +1499 13 467 412 442 +1500 132 142 633 128 +1501 184 180 172 170 +1502 631 332 424 554 +1503 531 573 579 51 +1504 521 571 563 18 +1505 599 625 282 340 +1506 622 630 605 575 +1507 562 442 362 412 +1508 193 180 170 141 +1509 50 644 636 615 +1510 443 466 20 19 +1511 616 542 533 491 +1512 413 594 564 52 +1513 621 53 600 405 +1514 362 562 446 27 +1515 403 547 321 481 +1516 403 481 321 329 +1517 562 442 412 10 +1518 493 459 536 599 +1519 493 599 536 282 +1520 450 86 328 517 +1521 413 602 610 46 +1522 29 23 28 20 +1523 223 409 433 491 +1524 621 59 537 54 +1525 13 362 412 446 +1526 439 422 11 14 +1527 639 473 631 422 +1528 450 612 584 517 +1529 450 482 612 517 +1530 413 641 602 52 +1531 447 10 24 562 +1532 531 573 534 579 +1533 380 345 468 604 +1534 587 427 444 618 +1535 613 567 600 534 +1536 218 386 238 643 +1537 643 238 423 386 +1538 347 496 352 604 +1539 63 345 517 614 +1540 584 612 63 517 +1541 629 431 585 418 +1542 153 431 585 629 +1543 463 539 478 607 +1544 463 539 607 16 +1545 564 609 475 575 +1546 533 529 402 616 +1547 376 630 564 518 +1548 645 54 600 621 +1549 380 468 472 604 +1550 604 468 472 352 +1551 380 468 549 472 +1552 570 187 373 374 +1553 606 413 641 640 +1554 413 610 602 640 +1555 458 467 13 9 +1556 467 458 13 371 +1557 11 422 26 543 +1558 25 17 425 15 +1559 646 536 280 493 +1560 646 624 280 536 +1561 647 430 44 42 +1562 618 544 220 379 +1563 648 6 486 7 +1564 648 6 538 486 +1565 403 633 547 481 +1566 403 328 633 481 +1567 483 127 628 578 +1568 486 7 12 14 +1569 53 56 352 496 +1570 340 288 284 625 +1571 283 340 284 625 +1572 561 352 472 468 +1573 86 450 328 403 +1574 329 403 481 328 +1575 455 288 284 372 +1576 501 288 284 455 +1577 376 530 575 630 +1578 630 376 609 575 +1579 430 479 42 647 +1580 621 405 600 534 +1581 22 28 20 443 +1582 643 238 229 423 +1583 481 633 547 142 +1584 558 428 551 652 +1585 509 611 331 508 +1586 513 514 331 611 +1587 509 513 331 611 +1588 601 9 1 3 +1589 289 288 344 501 +1590 515 32 399 34 +1591 403 321 349 329 +1592 392 229 643 238 +1593 618 445 544 379 +1594 618 587 544 445 +1595 531 613 534 573 +1596 629 153 448 628 +1597 538 473 597 486 +1598 597 473 639 486 +1599 650 31 608 346 +1600 607 505 580 21 +1601 288 455 289 372 +1602 289 455 288 501 +1603 376 530 590 575 +1604 49 594 475 575 +1605 356 279 281 274 +1606 550 209 444 500 +1607 362 412 446 562 +1608 529 433 491 223 +1609 455 372 284 283 +1610 465 501 455 289 +1611 465 289 344 501 +1612 445 209 444 587 +1613 153 642 127 628 +1614 294 385 291 414 +1615 283 625 459 599 +1616 613 531 51 573 +1617 636 573 613 51 +1618 557 621 568 537 +1619 558 551 520 5 +1620 500 209 202 627 +1621 635 200 541 574 +1622 595 200 635 574 +1623 558 652 551 5 +1624 534 579 573 615 +1625 605 575 630 564 +1626 31 346 32 608 +1627 631 424 639 422 +1628 383 346 638 26 +1629 469 575 564 413 +1630 15 560 332 598 +1631 15 554 332 560 +1632 586 557 534 615 +1633 573 586 534 615 +1634 332 543 598 593 +1635 543 332 598 15 +1636 609 575 564 630 +1637 554 631 332 453 +1638 424 554 543 422 +1639 608 346 651 650 +1640 487 495 430 479 +1641 645 621 534 557 +1642 645 621 600 534 +1643 542 491 541 574 +1644 541 635 574 491 +1645 636 644 586 573 +1646 573 586 615 644 +1647 543 634 598 593 +1648 497 127 642 628 +1649 598 543 15 634 +1650 25 15 543 634 +1651 473 519 597 453 +1652 595 574 635 491 +1653 636 51 615 573 +1654 644 573 636 615 +$EndElements diff --git a/test/user/testdata/shark_41_ascii_missing_node_index.msh b/test/user/testdata/shark_41_ascii_missing_node_index.msh new file mode 100644 index 00000000..ab7e2de6 --- /dev/null +++ b/test/user/testdata/shark_41_ascii_missing_node_index.msh @@ -0,0 +1,2973 @@ +$MeshFormat +4.1 0 8 +$EndMeshFormat +$Entities +0 0 0 1 +0 -0.07334360000000001 -0.08523339999999999 -0.0005566629999999989 0.07028570000000001 0.0819076 0.0752128 0 0 +$EndEntities +$Nodes +1 652 1 652 +3 0 0 652 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331 +332 +333 +334 +335 +336 +337 +338 +339 +340 +341 +342 +343 +344 +345 +346 +347 +348 +349 +350 +351 +352 +353 +354 +355 +356 +357 +358 +359 +360 +361 +362 +363 +364 +365 +366 +367 +368 +369 +370 +371 +372 +373 +374 +375 +376 +377 +378 +379 +380 +381 +382 +383 +384 +385 +386 +387 +388 +389 +390 +391 +392 +393 +394 +395 +396 +397 +398 +399 +400 +401 +402 +403 +404 +405 +406 +407 +408 +409 +410 +411 +412 +413 +414 +415 +416 +417 +418 +419 +420 +421 +422 +423 +424 +425 +426 +427 +428 +429 +430 +431 +432 +433 +434 +435 +436 +437 +438 +439 +440 +441 +442 +443 +444 +445 +446 +447 +448 +449 +450 +451 +452 +453 +454 +455 +456 +457 +458 +459 +460 +461 +462 +463 +464 +465 +466 +467 +468 +469 +470 +471 +472 +473 +474 +475 +476 +477 +478 +479 +480 +481 +482 +483 +484 +485 +486 +487 +488 +489 +490 +491 +492 +493 +494 +495 +496 +497 +498 +499 +500 +501 +502 +503 +504 +505 +506 +507 +508 +509 +510 +511 +512 +513 +514 +515 +516 +517 +518 +519 +520 +521 +522 +523 +524 +525 +526 +527 +528 +529 +530 +531 +532 +533 +534 +535 +536 +537 +538 +539 +540 +541 +542 +543 +544 +545 +546 +547 +548 +549 +550 +551 +552 +553 +554 +555 +556 +557 +558 +559 +560 +561 +562 +563 +564 +565 +566 +567 +568 +569 +570 +571 +572 +573 +574 +575 +576 +577 +578 +579 +580 +581 +582 +583 +584 +585 +586 +587 +588 +589 +590 +591 +592 +593 +594 +595 +596 +597 +598 +599 +600 +601 +602 +603 +604 +605 +606 +607 +608 +609 +610 +611 +612 +613 +614 +615 +616 +617 +618 +619 +620 +621 +622 +623 +624 +625 +626 +627 +628 +629 +630 +631 +632 +633 +634 +635 +636 +637 +638 +639 +640 +641 +642 +643 +644 +645 +646 +647 +648 +649 +650 +651 +652 +-0.07334359999999999 0.08167480000000001 0.056402 +-0.07291259999999999 0.0537921 0.00170478 +-0.072634 0.0799069 0.0578949 +-0.0715817 0.0520377 0.00292576 +-0.0701949 0.08025690000000001 0.0450431 +-0.06876980000000001 0.060971 0.00326551 +-0.06778000000000001 0.060358 0.00473741 +-0.06727959999999999 0.08092489999999999 0.0425553 +-0.0658074 0.0806443 0.0552302 +-0.064933 0.0788176 0.0453762 +-0.0636555 0.0610198 0.00141989 +-0.0636111 0.0566004 -0.000556663 +-0.0636791 0.0819076 0.0524468 +-0.0623445 0.0580268 0.00335683 +-0.0624856 0.06710579999999999 0.00581638 +-0.0601398 0.0781111 0.0317589 +-0.0599443 0.0685632 0.009924489999999999 +-0.0592787 0.0571239 0.00105116 +-0.0587906 0.07199990000000001 0.0117948 +-0.0575605 0.0730663 0.016213 +-0.057624 0.0811803 0.0403639 +-0.0572339 0.0769387 0.0223219 +-0.0559974 0.0749629 0.0235691 +-0.0542321 0.0763209 0.0344665 +-0.0540672 0.0649483 0.008218130000000001 +-0.0541685 0.06611350000000001 0.00437935 +-0.0532966 0.0805356 0.0466758 +-0.0517252 0.07611850000000001 0.0183218 +-0.0505257 0.06887699999999999 0.0152572 +-0.0503803 0.07726379999999999 0.0406423 +-0.0472855 0.0641041 0.00381053 +-0.0469016 0.0648796 0.00821733 +-0.0474599 0.07272679999999999 0.0265623 +-0.0464733 0.070912 0.0103373 +-0.0444756 0.07556740000000001 0.0221683 +-0.0440208 0.07743129999999999 0.0371107 +-0.0434135 0.0685101 0.0213943 +-0.0425401 0.0668787 0.0159114 +-0.0405353 0.07301630000000001 0.0309862 +-0.0386417 0.073548 0.0160682 +-0.037401 0.0664899 0.0122191 +-0.0358693 0.06894450000000001 0.0243885 +-0.0351058 0.06877709999999999 0.0124837 +-0.0333614 0.07116500000000001 0.0238503 +-0.0325564 0.0696271 0.024504 +-0.032455 0.0625178 0.0200737 +-0.0305469 0.0729973 0.0173921 +-0.0276941 0.06523859999999999 0.0128238 +-0.0272717 0.0628782 0.0141328 +-0.0263428 0.00735496 0.00505748 +-0.0256055 0.00658056 0.00327552 +-0.0252856 0.0610141 0.0227762 +-0.0250237 -0.00678856 0.00359213 +-0.0242889 -0.00589458 0.00589675 +-0.0216872 0.0639735 0.0255561 +-0.0215721 -0.0119744 0.00619585 +-0.0195136 0.0542304 0.0216195 +-0.0168343 0.06495339999999999 0.0236547 +-0.0161373 -0.00420129 0.00881529 +-0.0148726 0.0585475 0.0106707 +-0.0140647 0.0517836 0.0159197 +-0.0142986 0.0543801 0.0051496 +-0.0139611 -0.0178642 0.00651265 +-0.0139803 0.0554055 0.0115694 +-0.0124373 0.0606817 0.0122622 +-0.0127423 0.0580719 0.0285553 +-0.0127412 -0.07042320000000001 0.0234664 +-0.0126173 -0.0801905 0.022154 +-0.0125269 0.0592002 0.0346418 +-0.0122498 -0.080596 0.0191154 +-0.0121442 -0.0691943 0.0191352 +-0.0123618 0.0658492 0.0197519 +-0.0121018 -0.063334 0.0245151 +-0.0118539 0.0462485 0.0243954 +-0.0111067 0.0637388 0.0161162 +-0.0110042 -0.0624802 0.0276395 +-0.0109072 0.046219 0.0183571 +-0.0107037 -0.000325242 0.00950432 +-0.010183 -0.0121386 0.00674337 +-0.009774420000000001 -0.0638147 0.0162637 +-0.0097669 -0.06993340000000001 0.0156591 +-0.00942656 -0.0836042 0.0182705 +-0.009320999999999999 -0.0852334 0.0216727 +-0.00803502 0.0401179 0.0263407 +-0.00857808 -0.0579335 0.0163943 +-0.007931580000000001 -0.0190616 0.0121625 +-0.00782675 0.0573514 0.028038 +-0.00773028 -0.0620746 0.0302044 +-0.00764665 0.0537773 0.00961295 +-0.00721562 -0.0507362 0.0224357 +-0.00717408 -0.0528249 0.0179333 +-0.00651588 -0.00739691 0.013024 +-0.00691116 -0.00014073 0.00823716 +-0.00661131 0.044183 0.0123 +-0.00658663 0.0535365 0.0326225 +-0.00630954 -0.08506569999999999 0.0194796 +-0.00616497 -0.0797841 0.0261073 +-0.00582999 -0.0494502 0.0287705 +-0.00563359 0.0476479 0.00934546 +-0.00506609 -0.0425596 0.0250833 +-0.00453974 -0.0405694 0.0173853 +-0.00447266 0.0319291 0.0205877 +-0.00434886 0.0267225 0.00648417 +-0.00418386 0.0253438 0.008421959999999999 +-0.0041733 -0.0606038 0.0122716 +-0.00385183 0.0479538 0.00869149 +-0.00333705 0.051389 0.031593 +-0.00333565 -0.06938809999999999 0.0119551 +-0.00333748 -0.0650683 0.0110291 +-0.00292457 0.0475597 0.0319288 +-0.00280471 -0.0353375 0.0238411 +-0.00273019 -0.0493159 0.0135756 +-0.00255346 -0.0452657 0.0126112 +-0.00249178 -0.0598565 0.010934 +-0.00247351 -0.0533955 0.0149632 +-0.00280465 0.0288144 0.0300227 +-0.00225175 -0.030519 0.0236922 +-0.00205777 -0.0595101 0.00715068 +-0.0018581 -0.0627033 0.0116048 +-0.00150112 -0.0384203 0.0313885 +-0.00143547 -0.0337232 0.0176227 +-0.00136747 -0.062725 0.0150152 +-0.000884775 -0.0587825 0.0143119 +-0.000624659 -0.0247814 0.0257906 +-0.000489974 0.0225414 0.0188523 +-6.05566e-05 0.0171338 0.0234086 +0.00150381 0.0360475 0.00675461 +0.000282178 -0.0241462 0.0174969 +0.000347869 -0.06752370000000001 0.0324883 +0.000429839 -0.0422219 0.0349169 +0.00028168 -0.0273698 0.0312235 +0.000952705 -0.0267391 0.0143612 +0.00105244 0.0186951 0.00689988 +0.0011109 -0.0779453 0.014663 +0.00137887 0.00842564 0.0258445 +0.00107238 -0.0462225 0.00980545 +0.00158113 -0.0561697 0.005809 +0.00165921 -0.0142314 0.0114909 +0.00169065 -0.00330978 0.027848 +0.0017282 0.0264299 0.00972258 +0.00196109 -0.062067 0.0125082 +0.00198494 -0.0249792 0.0122768 +0.00206797 -0.0322322 0.0125632 +0.00219287 -0.00991015 0.0199027 +0.00223228 -0.065619 0.00972103 +0.00226787 -0.06664 0.0139131 +0.00233081 0.009707510000000001 0.0349608 +0.0023033 -0.0550711 0.0357611 +0.00284591 -0.06958739999999999 0.0109337 +0.00313658 0.0123831 0.0152878 +0.00325266 -0.000639164 0.0164744 +0.00354678 -0.0651674 0.00553443 +0.00434877 0.0392681 0.00656793 +0.0034004 -0.0624097 0.0143354 +0.00410027 0.052311 0.0146156 +0.00425687 -0.0110681 0.0377954 +0.0043501 -0.0020508 0.015115 +0.00444422 -0.0785667 0.0168482 +0.00471578 -0.008727459999999999 0.0133588 +0.00486541 0.0192794 0.0102326 +0.00475235 0.0259901 0.00777948 +0.00497525 -0.0797755 0.0244877 +0.0052286 0.0545416 0.0234287 +0.00513856 -0.0361953 0.00904286 +0.00543656 -0.016404 0.0117933 +0.00521097 0.0361763 0.0357574 +0.00563068 0.0458779 0.0101474 +0.00602624 -0.0598053 0.00448538 +0.00669265 -0.0730234 0.0300997 +0.00671975 -0.0647944 0.0149968 +0.00743572 0.0219428 0.00498754 +0.00806977 -0.06766220000000001 0.0106835 +0.008580020000000001 0.0185363 0.00804532 +0.00900922 -0.0527441 0.0382868 +0.00967438 -0.0310472 0.0412759 +0.009690270000000001 -0.0470756 0.00574739 +0.009825469999999999 -0.0777201 0.0238208 +0.010337 -0.0646559 0.00738197 +0.0103691 -0.0715108 0.0301524 +0.0108524 -0.06519229999999999 0.0107074 +0.0112352 0.0223598 0.00496048 +0.0115762 0.0360388 0.034027 +0.011811 0.0150563 0.0411225 +0.0119389 -0.07108730000000001 0.0142927 +0.011481 0.000850754 0.00890493 +0.0122581 0.0177891 0.00726338 +0.0126044 0.0285097 0.0071727 +0.0126077 -0.0410848 0.00487059 +0.01325 0.0245576 0.00385279 +0.0133342 -0.0301914 0.00695184 +0.0134526 -0.00467313 0.044297 +0.0140263 0.0415073 0.0128325 +0.0139319 -0.0627506 0.0126489 +0.0144402 0.0213321 0.0408733 +0.0145153 -0.0120242 0.00709154 +0.0145254 0.0314471 0.00762861 +0.0143606 -0.0539791 0.00638859 +0.0153705 -0.0588177 0.00913193 +0.0158483 0.0424843 0.0267153 +0.0161677 0.0082135 0.0752128 +0.0160709 -0.0693691 0.0267104 +0.0163112 0.021127 0.00658374 +0.0163956 0.0418119 0.0180916 +0.0166653 0.00513625 0.0449469 +0.0171438 -0.009394380000000001 0.0462661 +0.0174416 -0.0497054 0.0373642 +0.0174198 -0.06569369999999999 0.0159871 +0.0177387 0.0346114 0.0053358 +0.0178439 0.0247259 0.00729322 +0.018247 0.0346901 0.00258831 +0.0182074 -0.0318958 0.0424624 +0.0183988 -0.00142899 0.0496692 +0.0188182 -0.018825 0.0447569 +0.0188285 0.0147456 0.0461032 +0.0188626 0.015416 0.041072 +0.0190811 -0.00419709 0.06868580000000001 +0.0195945 0.0084326 0.064095 +0.0197498 -0.00217441 0.0583864 +0.0198208 0.00539755 0.0587622 +0.0200137 0.0324539 0.00354185 +0.020151 -0.0145671 0.0500049 +0.0203386 -0.00326709 0.07024469999999999 +0.0209148 0.00523036 0.0681576 +0.0208447 0.0121045 0.0546374 +0.0209724 0.009706330000000001 0.0633876 +0.020604 -0.0121123 0.00591309 +0.0212498 -0.0289526 0.00565549 +0.0216078 -0.0380775 0.00479088 +0.0216875 -0.00997672 0.0619769 +0.0220658 0.00705093 0.0456869 +0.0223002 -0.0558455 0.0110476 +0.0223137 -0.0154618 0.0494217 +0.0229336 0.00417573 0.0589573 +0.0231427 0.0278288 0.0125965 +0.0231751 0.027241 0.0309726 +0.0233259 0.0160686 0.00756079 +0.0234095 0.0318943 0.0199392 +0.0234462 -0.00393483 0.0583985 +0.0235915 -0.0597066 0.0170609 +0.0240196 -0.0108777 0.0466362 +0.024123 -0.00330273 0.0464733 +0.0242099 -0.0321428 0.0398591 +0.0244244 0.00347947 0.0416421 +0.024564 -0.0175604 0.0433407 +0.0253979 -0.0453083 0.0344803 +0.0256103 0.0267734 0.0284514 +0.0259312 -0.0445208 0.00878379 +0.025959 -0.0133125 0.00624018 +0.0265967 -0.0369666 0.00635268 +0.0273245 -0.0066598 0.0412078 +0.0277597 -0.0467651 0.0304517 +0.0275944 -0.0515878 0.0207552 +0.0282687 0.0208205 0.0174814 +0.0290859 0.0112094 0.012597 +0.0293048 -0.0474855 0.0256026 +0.0296506 -0.0466043 0.0156453 +0.0304236 0.0134394 0.031696 +0.0304518 -0.0291908 0.00746031 +0.03126 -0.044124 0.016095 +0.0321715 -0.043346 0.0242104 +0.0322352 -0.0402733 0.0141242 +0.0323149 0.01052 0.0200521 +0.0324768 -0.0397188 0.0271188 +0.0325431 -0.0291932 0.0340382 +0.0332479 -0.0329826 0.0117351 +0.0338676 -0.0346121 0.0252676 +0.0341522 -0.00293196 0.033596 +0.0341882 -0.0361716 0.0179088 +0.0344969 -0.0256263 0.0309923 +0.0345138 -0.00958586 0.0123416 +0.0348872 -0.0128566 0.0339912 +0.0349524 -0.0273994 0.0177976 +0.0349556 -0.000677158 0.0209767 +0.0350004 -0.028049 0.008761420000000001 +0.0353194 -0.0100316 0.0154749 +0.0354214 -0.0195455 0.0173172 +0.0355775 -0.0309821 0.0107592 +0.0360305 -0.0150581 0.0232372 +0.0363938 -0.0285041 0.0132933 +0.0374738 -0.00607371 0.0123945 +0.041317 -0.0210454 0.0131228 +0.0425886 -0.0120136 0.0129537 +0.0475164 -0.00753527 0.00853843 +0.0492593 -0.00704914 0.009380670000000001 +0.0496752 -0.0170405 0.0106038 +0.0498676 -0.0259318 0.00619626 +0.052402 -0.022331 0.00866719 +0.0516897 -0.011391 0.0103437 +0.0559595 -0.0106346 0.00698866 +0.0596531 -0.0214295 0.0059579 +0.066312 -0.0158462 0.00759335 +0.0672852 -0.00331292 0.00667068 +0.0687074 -0.0027598 0.00829441 +0.0687083 -0.008451500000000001 0.00881385 +0.07028570000000001 -0.00694567 0.00665748 +0.02471 0.00101921 0.00688758 +0.00641783 -0.0341512 0.0233596 +0.024018 0.00854392 0.00722419 +0.0251696 0.009421270000000001 0.00784613 +-0.019815 0.0686939 0.0189821 +0.0416697 -0.017118 0.00864259 +-0.00440288 -0.06984319999999999 0.0205811 +-0.0033606 0.0600219 0.0217676 +0.0268544 0.00322876 0.008082499999999999 +0.00855449 0.0107052 0.00928038 +0.0219179 0.00585482 0.0121236 +0.0199208 0.0175811 0.0336776 +0.0210521 -0.0362113 0.0256186 +0.0339797 -0.00194129 0.0163861 +0.03202 0.000337126 0.0126992 +0.0119633 0.0163586 0.0147908 +0.0248778 0.0056119 0.0321775 +0.00892971 -0.0563678 0.0287948 +0.0174837 0.027107 0.0210333 +-0.0170518 0.00346089 0.00554363 +0.0144974 -0.0120686 0.0314959 +0.00336155 -0.00103205 0.0364574 +0.00707711 -0.0204903 0.0185209 +0.010517 -0.00309481 0.0232445 +-0.00559352 0.0373259 0.0172753 +-0.00523735 -0.0230725 0.0111224 +0.0151072 -0.0538804 0.0213778 +0.0347571 -0.0188174 0.0105515 +0.0278657 -0.0183642 0.0156758 +-0.00338013 -0.0543805 0.0329679 +-0.0196332 0.0593213 0.0251138 +0.06481629999999999 -0.0143432 0.00627944 +-0.00336175 -0.0187472 0.00979996 +-0.0059938 -0.0214388 0.00941436 +0.0204933 0.0262773 0.00994486 +0.0153554 0.00838654 0.0105168 +-0.064082 0.064994 0.00682263 +-0.0406296 0.0703091 0.0249838 +-0.0197677 0.0563929 0.0156108 +-0.0506931 0.0781816 0.0304629 +0.0171972 -0.00100568 0.011485 +0.0314619 -0.0225976 0.00774901 +-0.00980694 0.0515267 0.0104574 +-0.00435185 0.0493969 0.0137744 +0.0449063 -0.0117353 0.00859937 +0.00159087 -0.0450385 0.027858 +-0.00469537 -0.06372510000000001 0.0233918 +0.0424219 -0.0285632 0.00857374 +0.0603894 -0.00835109 0.009350529999999999 +-0.0147113 -0.0156046 0.009183759999999999 +-0.0528157 0.0611754 0.00480955 +-0.0173765 -0.008871489999999999 0.00520522 +0.0108104 0.02268 0.0130558 +-0.00899905 -0.0208443 0.00915416 +-0.0449914 0.0768094 0.0302276 +-0.0408502 0.06658 0.008368489999999999 +-0.0199988 -0.0118916 0.004906 +0.00337131 0.0455887 0.0238561 +0.00477413 -0.0721541 0.0211645 +-0.00344193 -0.049333 0.032475 +0.0427245 -0.0268877 0.00738607 +0.0272704 -0.0238375 0.00669928 +-0.00610544 -0.0476638 0.0181008 +-0.00760153 0.0503529 0.00747858 +0.0131109 -0.0422224 0.0405109 +0.00214561 -0.0490294 0.0151357 +-0.0598224 0.0805424 0.0511855 +-0.0204542 0.0588165 0.013102 +0.059357 -0.0190886 0.00813027 +-0.00100716 0.0422264 0.0325724 +0.0325535 -0.0244764 0.012522 +-0.000431427 -0.0574818 0.0137747 +0.0114251 0.0275734 0.00440942 +0.00337666 -0.0559724 0.0148659 +-0.0262911 0.0586227 0.0207785 +-0.0699467 0.0813567 0.0499003 +0.0494602 -0.0133111 0.00757754 +0.00758285 0.0333008 0.0104911 +0.00657287 0.032122 0.00603963 +0.000332803 -0.0511328 0.0180756 +-0.021764 0.0620607 0.0118108 +-0.0454672 0.075167 0.035911 +0.00139884 0.045926 0.0128133 +0.0176314 0.0311493 0.00370344 +-0.0159418 -0.0158578 0.00793814 +-0.0229387 0.06916410000000001 0.0166572 +-0.00133409 -0.0449329 0.0187829 +-0.0538019 0.0611146 0.00198764 +0.0305208 -0.00256491 0.0101919 +0.0623596 -0.00697151 0.00683979 +0.0236819 -0.00777996 0.0526871 +0.0118138 -0.0144241 0.0430193 +0.0137156 -0.00365078 0.00732253 +-0.0257884 0.0686739 0.0150694 +-0.0530331 0.060812 0.00248197 +-0.000421194 -0.0523335 0.008791770000000001 +0.0193846 -0.00072024 0.0649221 +0.00485856 0.0133946 0.0114741 +-0.0053823 -0.0743714 0.0141262 +0.016958 0.0166471 0.00740593 +0.0429338 -0.0266961 0.0110582 +-0.06504749999999999 0.05473 0.00191127 +0.00924818 0.0356698 0.00715588 +-0.042468 0.0652669 0.00790867 +0.00699205 0.0348997 0.00576165 +-0.012123 0.00171435 0.00688121 +0.017741 0.00126373 0.0717161 +-0.00477874 -0.0228765 0.0123522 +-0.05496 0.0793832 0.0329037 +-0.0253736 -0.000654191 0.00342534 +0.0220159 -0.0128389 0.0555838 +0.0187915 0.00366305 0.06539010000000001 +-0.0635923 0.0794618 0.0351284 +0.0187293 0.00901455 0.0689246 +-0.0507436 0.0790633 0.0364811 +0.00440962 0.0291856 0.00589534 +-0.0610541 0.08157639999999999 0.0467801 +-0.0264169 0.06418980000000001 0.0180225 +0.0590681 -0.0129818 0.009692930000000001 +0.0316732 -0.013669 0.008927310000000001 +-0.0368828 0.0732351 0.028231 +0.0147007 -0.0293577 0.0425282 +-0.00226105 0.042112 0.008184220000000001 +-0.022404 0.068624 0.0211714 +0.018834 0.0296379 0.0101126 +0.0545664 -0.023882 0.00596013 +-0.0610274 0.0626039 0.00623226 +0.0209345 -0.0123916 0.0558755 +-0.064258 0.0639612 0.00701622 +-0.0530259 0.07099660000000001 0.0104874 +-0.000350232 0.0328643 0.009503569999999999 +0.0179821 0.0260225 0.00525665 +-0.071629 0.0809096 0.0500374 +0.0431333 -0.00662611 0.0109755 +-0.0367738 0.072104 0.0272887 +-0.00147996 0.0424733 0.00778004 +-0.0489442 0.0792518 0.0424775 +0.0178184 0.008309230000000001 0.0698262 +-0.00256208 -0.0518644 0.0119693 +-0.0024457 0.0347988 0.0115191 +-0.0226391 0.067054 0.0236986 +-0.0250562 0.070839 0.0181046 +0.0157661 -0.010775 0.0444953 +-0.0587069 0.0610686 0.00549325 +-0.0561989 0.0607157 0.00436391 +0.0028322 0.0311045 0.0076099 +-0.061857 0.079748 0.0514834 +-0.0580072 0.07448539999999999 0.0170926 +0.017366 0.0281829 0.00449304 +0.0175246 0.0303053 0.00632184 +-0.0583716 0.0812348 0.0494755 +-0.06276379999999999 0.08110589999999999 0.0418948 +0.009583370000000001 0.0391723 0.00889538 +0.0164997 0.0327763 0.00400793 +-0.0100537 -0.019407 0.0104569 +0.0535082 -0.023589 0.00757618 +-0.0184567 0.0672393 0.0165986 +-0.0660887 0.06395149999999999 0.00557639 +-0.008500499999999999 0.0591911 0.0132991 +0.0527123 -0.00658592 0.00801901 +0.00664445 0.0147496 0.00979726 +-0.0323364 0.06468409999999999 0.013176 +-0.06849810000000001 0.0817682 0.0541475 +0.0424951 -0.00680449 0.0104665 +-0.01583 0.06382989999999999 0.0140017 +-0.0408586 0.07478079999999999 0.0276312 +-0.0213675 0.00505684 0.00440033 +-0.0609542 0.0784149 0.029815 +0.0458286 -0.0196104 0.0115924 +0.0619857 -0.0044448 0.00717137 +-0.0549453 0.0736446 0.0144159 +-0.0660739 0.0797747 0.0511232 +-0.0150243 -0.0138696 0.00597473 +-0.0208919 0.06642729999999999 0.014553 +-0.0583912 0.07667309999999999 0.0277458 +-0.00499489 -0.0492059 0.0154875 +-0.0177596 -0.0149926 0.00640227 +-0.0656257 0.0638276 0.00437301 +-0.00111824 -0.0505712 0.010634 +-0.0234714 0.0595273 0.0150887 +-0.0117477 -0.00786715 0.0107629 +-0.0329423 0.0662408 0.012525 +-0.0588644 0.0778049 0.0265316 +-0.038272 0.07101209999999999 0.0277124 +0.0147178 0.0228905 0.00513556 +-0.00242697 -0.0228032 0.0106496 +-0.00998317 -0.0196685 0.00798312 +0.00194711 0.0338412 0.00734265 +-0.0101071 0.0571173 0.0108272 +-0.000192036 0.0305177 0.010316 +-0.06622359999999999 0.0609953 0.00234663 +-0.0383437 0.071981 0.0290737 +0.0464353 -0.0271448 0.00729223 +-0.0113654 0.0558876 0.00985606 +-0.0600686 0.0581853 0.00037707 +0.0184892 0.00651809 0.072001 +-0.0272353 0.0661385 0.0125002 +0.0386787 -0.009397559999999999 0.0110365 +-0.00702298 -0.0554164 0.0301677 +-0.0387296 0.0725599 0.0291973 +-0.0195884 -0.009713039999999999 0.00731553 +0.0009803979999999999 0.0340005 0.008311529999999999 +-0.00251349 -0.0493306 0.0137872 +-0.0208118 0.00468072 0.00662791 +0.0145465 0.0247675 0.00685396 +0.0539643 -0.00601143 0.00911787 +0.0615879 -0.00432066 0.00875869 +-0.0649217 0.0800024 0.0383643 +0.00460493 0.008497380000000001 0.0127005 +-0.0606311 0.0803611 0.0379233 +-0.00316884 0.0400824 0.00969248 +-0.0308482 0.067467 0.0126012 +0.0120049 0.00511369 0.00824306 +0.0117314 0.0134932 0.00784586 +0.0067401 0.0222359 0.00786688 +0.000365941 0.0444987 0.0334101 +0.00589042 0.0427357 0.0325284 +0.0134556 0.013691 0.0071386 +0.0155774 0.00572549 0.00675779 +-0.0442054 0.0654197 0.00607699 +0.00863004 0.0184766 0.00878081 +-0.0111016 -0.0170398 0.0107756 +-0.0162643 0.06208 0.0123266 +-0.06706429999999999 0.0628756 0.0047451 +-0.0673064 0.07917689999999999 0.0489333 +-0.0566743 0.0588231 0.00264455 +-0.07138410000000001 0.080001 0.0523997 +-0.0690781 0.0794039 0.0521145 +-0.0589744 0.07029879999999999 0.0123753 +-0.0108026 0.05228 0.00636676 +-0.0113486 0.0541547 0.00728553 +-0.0299136 0.06862409999999999 0.0165753 +0.0505332 -0.0225927 0.00635398 +0.0180077 0.0031318 0.07043870000000001 +-0.0235313 0.0640143 0.012641 +-0.0235569 0.00584404 0.00381922 +0.0384718 -0.0113423 0.0144484 +0.0182407 0.00232532 0.0728388 +-0.0235752 0.00407866 0.00373027 +-0.011585 0.0522432 0.00647843 +0.0400312 -0.00904366 0.0126741 +-0.0178591 -0.000359808 0.00797485 +-0.067167 0.06255139999999999 0.00392853 +-0.0596438 0.0779391 0.0290601 +0.0013543 0.0302152 0.00901705 +0.0168301 0.00522322 0.0737244 +0.0174324 0.00448014 0.0738384 +-0.0618546 0.0649931 0.00590465 +0.0194429 0.0304209 0.00452872 +-0.0236633 0.0648084 0.0124456 +-0.00249493 -0.0562542 0.012985 +-0.0025263 -0.0246783 0.0125409 +-0.0396392 0.0718092 0.02876 +-0.0158083 -0.0164708 0.00645267 +0.016879 0.0245859 0.0055459 +-0.06884990000000001 0.0811361 0.0461884 +0.0290982 -0.00647478 0.008279069999999999 +-0.041817 0.0761358 0.0343691 +-0.0642688 0.0653922 0.00517065 +-0.0162175 0.00239503 0.00694561 +0.00467524 0.0360758 0.00643588 +-0.0222973 0.0035638 0.00646752 +-0.0708092 0.0801688 0.0482801 +-0.0549524 0.07870829999999999 0.0296023 +-0.06310540000000001 0.0672415 0.00811831 +-0.0155444 -0.0163359 0.0060847 +-0.0574097 0.07880470000000001 0.0473507 +-0.0558952 0.0591814 0.001764 +-0.0177409 0.0619627 0.0144786 +-0.00178349 -0.0487397 0.0125937 +-0.0111058 0.0522074 0.008299040000000001 +-0.0260139 0.00360897 0.00461987 +-0.0204566 0.00423454 0.00564674 +0.00612936 0.0370467 0.00680554 +0.010446 0.0313554 0.00705031 +-0.0569353 0.05965 0.00118235 +-0.0506685 0.0625792 0.00279292 +-0.0249761 0.00485573 0.00443819 +0.0172421 0.00725128 0.07382619999999999 +-0.0219613 0.06430039999999999 0.0138184 +-0.00260185 -0.0513557 0.0142694 +-0.0167422 0.00259292 0.00779623 +0.00214524 0.0341103 0.00650831 +-0.0236765 0.00572293 0.004305 +-0.0616879 0.0784644 0.0353636 +-0.0125522 0.0533024 0.00573952 +-0.00373263 -0.048886 0.014509 +-0.00253347 -0.0472982 0.0131992 +-0.0128746 -0.017623 0.00940414 +-5.43548e-05 0.0393803 0.00728201 +-0.0258702 0.00405717 0.00525282 +0.0183599 0.0265636 0.00640112 +0.0459896 -0.0257989 0.0100883 +-0.0295424 0.06805940000000001 0.0247957 +-0.0245383 0.0634107 0.0123732 +0.0066096 0.0377811 0.00691952 +-0.0450015 0.0646553 0.00575343 +-0.0622505 0.0661482 0.00839783 +-0.0256248 0.0608105 0.0161665 +0.017488 0.00853314 0.07209649999999999 +-0.0596734 0.07050969999999999 0.009924850000000001 +-0.06657979999999999 0.06286890000000001 0.00493615 +-0.0624322 0.0664941 0.0080812 +0.0436037 -0.00911409 0.009504510000000001 +-0.0258241 0.00183578 0.00455937 +-0.07027029999999999 0.07969130000000001 0.0546337 +-0.027947 0.06304949999999999 0.0231884 +-0.0601839 0.07046330000000001 0.0106076 +-0.019796 -0.0130118 0.0069497 +-0.0183149 0.06305479999999999 0.012418 +-0.0302535 0.0701272 0.02364 +-0.0574291 0.07908510000000001 0.0314511 +-0.0506885 0.0650762 0.00396145 +-0.021101 0.0616869 0.0137094 +-0.0331684 0.0670427 0.023997 +0.0134393 0.00644533 0.00718965 +-0.0111807 -0.0194906 0.00818236 +-0.0255718 0.00304117 0.00332801 +-0.0126697 -0.015488 0.00653208 +-0.0247074 0.00660999 0.00551935 +0.0173416 0.0031807 0.0727906 +0.0172416 0.0236783 0.00588169 +0.0190309 0.0293428 0.00437137 +0.016715 0.00646681 0.0747173 +-0.0362286 0.072292 0.023504 +-0.0193589 -0.00042516 0.00470745 +-0.0218861 0.06436310000000001 0.0125137 +-0.0102557 0.0512168 0.00711881 +0.0404202 -0.00631757 0.0116411 +0.0462272 -0.00679819 0.0101561 +-0.0259792 0.0656558 0.0150971 +0.0162732 0.0229634 0.00624384 +0.00353474 0.0364474 0.008433390000000001 +4.6368e-06 0.0388726 0.009730829999999999 +-0.0216501 0.0633078 0.012475 +-0.06535530000000001 0.0635995 0.0060088 +-0.0129397 0.0533345 0.00604151 +-0.00189413 -0.0244631 0.013557 +-0.0610974 0.0673557 0.00916116 +0.0169636 0.00823874 0.0726305 +-0.0262169 0.00566462 0.00486021 +-0.00105663 -0.050339 0.013034 +-0.0522352 0.0618469 0.00239028 +-0.06586110000000001 0.0623674 0.00600767 +-0.0308719 0.0671807 0.0240148 +-0.0271033 0.0631674 0.0232081 +0.000463176 0.0377435 0.00713404 +0.0197653 -0.0105149 0.0573133 +-0.0261272 0.00574879 0.00514751 +-0.0256133 0.00236555 0.00535812 +0.0395658 -0.00664927 0.0115095 +-0.0346515 0.0704144 0.0260764 +-0.0676857 0.0619198 0.00410476 +-0.0352382 0.07226829999999999 0.0261851 +-0.0489272 0.0632235 0.00329626 +-0.0514659 0.0617489 0.00295197 +-0.070483 0.0805389 0.0464472 +$EndNodes +$Elements +1 1654 1 1654 +3 0 4 1654 +1 26 15 543 25 +2 227 308 190 188 +3 203 353 199 163 +4 331 305 504 150 +5 142 328 128 138 +6 490 439 18 571 +7 364 289 287 414 +8 296 336 304 298 +9 564 419 300 381 +10 398 569 373 591 +11 486 473 639 422 +12 338 89 566 489 +13 332 554 543 424 +14 80 67 71 302 +15 149 146 109 108 +16 98 90 375 342 +17 341 308 325 313 +18 147 314 126 116 +19 124 318 156 131 +20 245 322 206 308 +21 348 311 516 186 +22 135 150 319 151 +23 147 314 307 311 +24 464 588 301 528 +25 461 33 35 333 +26 196 192 373 314 +27 108 81 302 122 +28 366 258 227 357 +29 511 107 512 353 +30 146 170 354 172 +31 297 175 156 130 +32 130 297 175 308 +33 318 159 319 195 +34 154 123 122 342 +35 261 308 259 260 +36 132 142 128 318 +37 241 250 240 205 +38 226 227 248 324 +39 575 609 475 49 +40 375 91 123 90 +41 260 308 255 251 +42 517 612 63 482 +43 120 117 131 297 +44 318 131 297 156 +45 147 319 311 307 +46 131 120 297 130 +47 120 297 111 117 +48 308 174 206 360 +49 148 313 325 175 +50 148 313 175 174 +51 302 80 122 81 +52 107 353 511 110 +53 322 231 198 197 +54 61 58 564 57 +55 240 386 212 221 +56 121 297 143 117 +57 121 297 117 111 +58 307 235 314 182 +59 307 314 166 182 +60 417 308 175 316 +61 308 175 360 417 +62 601 9 458 1 +63 459 429 536 599 +64 211 242 206 308 +65 528 588 301 356 +66 316 297 308 175 +67 197 188 308 228 +68 231 308 228 197 +69 231 197 322 308 +70 188 197 308 361 +71 322 361 308 197 +72 259 308 256 255 +73 298 306 304 299 +74 302 342 146 122 +75 251 322 245 308 +76 298 306 299 236 +77 342 302 169 129 +78 157 319 331 150 +79 190 195 324 227 +80 146 342 354 154 +81 190 297 308 324 +82 236 254 306 299 +83 354 179 201 322 +84 308 297 188 361 +85 361 188 164 297 +86 195 165 190 318 +87 307 215 257 235 +88 194 235 215 307 +89 174 129 148 313 +90 169 313 129 174 +91 322 255 251 201 +92 366 265 308 258 +93 227 308 258 366 +94 258 308 249 265 +95 227 308 228 258 +96 448 192 373 196 +97 228 308 249 258 +98 296 298 514 336 +99 125 150 348 126 +100 125 160 348 150 +101 244 264 242 316 +102 264 316 244 271 +103 224 233 225 219 +104 107 353 163 199 +105 217 223 219 225 +106 308 174 313 206 +107 206 313 179 174 +108 241 230 212 233 +109 241 233 212 218 +110 267 278 312 273 +111 267 312 262 273 +112 206 179 322 245 +113 242 245 206 308 +114 144 319 159 157 +115 265 308 266 272 +116 218 219 392 233 +117 264 324 316 271 +118 324 308 264 316 +119 297 318 117 131 +120 128 117 318 124 +121 354 207 201 177 +122 207 177 354 184 +123 155 163 353 203 +124 131 297 156 130 +125 395 330 236 202 +126 164 142 318 190 +127 253 314 234 311 +128 307 314 147 166 +129 331 234 253 254 +130 306 236 298 331 +131 156 297 316 175 +132 324 319 318 316 +133 297 324 316 308 +134 373 314 102 125 +135 167 155 378 192 +136 278 324 272 269 +137 278 276 272 324 +138 319 159 157 336 +139 267 257 312 243 +140 307 215 243 257 +141 156 297 318 316 +142 207 354 170 184 +143 124 144 139 156 +144 267 312 250 243 +145 144 151 139 319 +146 318 316 319 144 +147 316 139 319 144 +148 139 144 316 156 +149 316 191 312 319 +150 316 191 317 156 +151 313 308 175 174 +152 253 234 331 311 +153 331 395 234 236 +154 272 265 308 366 +155 103 140 133 510 +156 235 199 246 314 +157 246 237 314 199 +158 144 151 319 157 +159 92 157 151 144 +160 92 159 157 144 +161 395 234 236 330 +162 395 330 202 348 +163 348 330 202 209 +164 324 312 316 271 +165 266 308 324 272 +166 324 366 308 227 +167 242 264 245 308 +168 272 266 269 324 +169 135 151 319 139 +170 40 35 28 29 +171 88 148 129 342 +172 325 342 148 88 +173 314 116 147 166 +174 77 353 320 94 +175 331 262 319 306 +176 319 317 139 316 +177 450 329 482 328 +178 183 307 147 166 +179 188 361 176 197 +180 169 179 313 174 +181 314 196 348 373 +182 102 84 116 353 +183 102 77 84 353 +184 191 147 319 317 +185 307 262 257 312 +186 307 257 246 235 +187 307 257 262 246 +188 128 318 144 124 +189 246 314 237 253 +190 314 203 237 234 +191 142 128 318 138 +192 253 237 234 314 +193 306 319 331 336 +194 307 314 235 246 +195 316 250 312 191 +196 450 403 349 329 +197 121 297 101 143 +198 382 164 101 297 +199 369 198 322 193 +200 264 266 324 269 +201 322 354 170 207 +202 322 170 193 207 +203 353 84 116 110 +204 70 302 68 83 +205 331 311 234 395 +206 323 493 282 301 +207 269 278 324 271 +208 278 312 324 271 +209 207 170 180 184 +210 207 170 193 180 +211 325 130 175 308 +212 146 354 170 154 +213 354 302 342 146 +214 161 348 510 181 +215 182 314 199 235 +216 322 354 369 170 +217 231 207 322 198 +218 313 322 375 341 +219 375 361 341 322 +220 322 207 193 198 +221 297 143 164 101 +222 221 213 240 232 +223 190 188 308 297 +224 341 361 375 382 +225 341 308 313 322 +226 134 158 184 354 +227 247 308 261 249 +228 263 308 260 251 +229 318 319 159 144 +230 309 262 306 319 +231 250 204 243 312 +232 448 192 167 378 +233 37 333 620 35 +234 37 33 333 35 +235 297 318 316 324 +236 167 448 378 153 +237 212 218 233 219 +238 88 325 342 494 +239 246 307 314 253 +240 307 253 246 262 +241 126 311 150 348 +242 388 611 336 514 +243 348 234 420 314 +244 236 254 331 306 +245 348 314 311 234 +246 211 308 360 417 +247 373 102 320 125 +248 316 250 191 438 +249 250 205 191 438 +250 254 262 306 309 +251 254 309 306 310 +252 299 254 306 310 +253 331 262 306 254 +254 292 294 295 293 +255 194 307 215 204 +256 304 306 384 299 +257 267 312 257 262 +258 353 192 378 155 +259 319 159 336 195 +260 353 192 373 378 +261 336 185 388 195 +262 312 250 271 267 +263 271 250 312 316 +264 261 249 308 265 +265 268 308 265 261 +266 247 308 249 228 +267 227 195 324 226 +268 366 324 415 337 +269 337 366 324 357 +270 190 195 318 324 +271 156 318 124 144 +272 263 266 308 264 +273 251 263 308 264 +274 197 198 322 369 +275 154 354 369 342 +276 188 308 228 227 +277 79 328 138 92 +278 316 317 139 156 +279 360 175 308 174 +280 255 251 308 322 +281 255 256 252 308 +282 247 228 231 308 +283 247 308 231 256 +284 134 149 394 354 +285 83 162 96 302 +286 161 373 140 348 +287 88 67 302 68 +288 302 97 88 68 +289 512 166 314 182 +290 420 192 314 234 +291 348 330 420 234 +292 192 314 234 203 +293 91 123 105 115 +294 394 70 302 81 +295 309 273 262 319 +296 319 262 312 273 +297 67 302 68 70 +298 271 278 312 267 +299 66 57 326 58 +300 188 136 176 361 +301 157 331 185 504 +302 136 361 188 164 +303 244 250 271 316 +304 71 302 67 70 +305 244 213 232 240 +306 81 302 71 70 +307 354 149 108 146 +308 314 237 203 199 +309 506 378 435 629 +310 244 438 316 213 +311 97 302 169 162 +312 244 316 438 250 +313 313 129 342 169 +314 382 113 101 164 +315 506 435 378 94 +316 91 123 85 105 +317 308 264 245 251 +318 242 264 308 316 +319 450 349 482 329 +320 314 373 348 125 +321 92 138 159 144 +322 395 311 234 348 +323 278 273 324 312 +324 373 378 435 320 +325 147 311 319 135 +326 126 311 135 150 +327 126 135 311 147 +328 314 348 311 126 +329 83 302 82 70 +330 378 435 629 373 +331 195 159 165 318 +332 316 312 324 319 +333 156 175 316 387 +334 336 298 514 331 +335 88 342 129 302 +336 319 307 331 311 +337 253 314 311 307 +338 311 331 253 307 +339 297 341 308 130 +340 314 348 126 125 +341 147 314 311 126 +342 61 339 99 338 +343 250 204 312 191 +344 305 185 508 331 +345 211 242 308 316 +346 211 308 417 316 +347 213 316 211 417 +348 214 215 230 204 +349 244 316 242 211 +350 244 211 213 316 +351 465 501 344 502 +352 108 354 302 394 +353 313 129 148 342 +354 337 324 415 248 +355 337 258 366 357 +356 121 101 297 111 +357 382 101 111 297 +358 157 159 185 336 +359 226 336 195 324 +360 307 262 331 253 +361 307 262 319 331 +362 331 254 253 262 +363 248 336 552 296 +364 319 324 195 336 +365 248 296 226 336 +366 324 248 336 552 +367 147 183 191 307 +368 282 281 276 323 +369 281 323 282 301 +370 109 119 105 122 +371 297 143 117 318 +372 109 122 105 80 +373 308 366 324 272 +374 297 318 324 190 +375 297 190 164 318 +376 214 204 230 212 +377 224 212 214 230 +378 297 143 318 164 +379 264 308 324 266 +380 264 269 324 271 +381 132 117 143 318 +382 130 297 341 120 +383 341 130 120 98 +384 277 343 356 279 +385 325 308 175 313 +386 109 81 108 122 +387 109 122 108 146 +388 348 234 395 330 +389 341 111 120 297 +390 341 100 98 120 +391 341 111 100 120 +392 226 336 324 248 +393 318 319 324 195 +394 275 270 324 309 +395 309 336 324 319 +396 552 270 336 324 +397 273 309 275 324 +398 403 328 329 450 +399 382 111 341 297 +400 361 322 308 341 +401 361 341 308 297 +402 342 85 73 90 +403 342 73 85 80 +404 323 324 366 276 +405 361 297 164 382 +406 96 82 83 302 +407 45 647 44 42 +408 179 354 201 177 +409 53 621 54 347 +410 117 124 131 318 +411 156 144 316 318 +412 369 198 193 141 +413 342 302 88 67 +414 67 80 342 302 +415 73 80 342 67 +416 342 73 67 76 +417 372 528 289 285 +418 285 528 289 287 +419 355 98 325 494 +420 122 119 105 123 +421 394 82 134 302 +422 494 88 76 342 +423 109 81 122 80 +424 447 580 503 505 +425 114 118 141 145 +426 311 150 319 135 +427 108 122 302 146 +428 204 307 183 194 +429 191 204 307 183 +430 382 101 100 111 +431 382 111 100 341 +432 318 159 138 144 +433 588 281 301 356 +434 87 61 77 57 +435 318 159 165 138 +436 7 12 2 486 +437 316 191 319 317 +438 208 196 449 445 +439 322 369 354 313 +440 354 158 177 162 +441 354 169 162 179 +442 313 369 354 342 +443 179 162 354 177 +444 130 98 341 355 +445 325 130 341 355 +446 337 357 324 248 +447 324 357 227 248 +448 588 281 464 301 +449 375 341 382 98 +450 454 75 61 155 +451 353 77 84 74 +452 331 305 185 504 +453 311 331 319 150 +454 378 339 167 106 +455 318 190 142 165 +456 138 142 165 318 +457 18 12 397 14 +458 298 514 331 513 +459 118 137 141 168 +460 298 331 236 395 +461 395 298 331 513 +462 93 157 92 159 +463 354 158 184 177 +464 151 157 92 93 +465 78 93 151 92 +466 378 448 629 153 +467 102 314 126 125 +468 126 116 314 102 +469 61 72 303 75 +470 39 461 350 553 +471 350 39 33 461 +472 311 331 513 395 +473 311 331 305 509 +474 353 102 314 116 +475 204 215 243 307 +476 106 153 167 378 +477 97 162 83 302 +478 107 353 199 512 +479 297 188 164 190 +480 147 319 139 135 +481 77 353 87 74 +482 353 203 199 314 +483 512 314 353 199 +484 37 38 29 35 +485 485 140 373 125 +486 398 448 373 196 +487 196 570 373 398 +488 324 248 552 415 +489 415 270 552 324 +490 52 57 594 564 +491 285 289 414 287 +492 438 250 205 240 +493 524 425 25 17 +494 29 25 524 425 +495 87 77 61 353 +496 93 92 138 159 +497 93 92 79 138 +498 203 192 353 155 +499 192 353 314 203 +500 88 302 129 97 +501 169 342 354 302 +502 147 319 317 139 +503 435 426 629 373 +504 197 168 369 176 +505 369 176 361 197 +506 157 151 319 150 +507 307 319 312 191 +508 312 307 191 204 +509 628 373 441 374 +510 513 331 311 509 +511 49 594 413 46 +512 303 163 87 61 +513 146 342 154 122 +514 274 366 415 337 +515 274 258 366 337 +516 87 57 74 66 +517 304 306 336 384 +518 204 250 205 191 +519 110 74 66 87 +520 163 87 61 353 +521 204 205 250 241 +522 387 438 213 316 +523 150 160 348 311 +524 313 369 342 375 +525 313 322 369 375 +526 97 129 169 302 +527 504 305 393 150 +528 181 348 500 187 +529 610 527 42 44 +530 44 527 42 620 +531 311 305 456 509 +532 311 509 456 516 +533 365 512 166 116 +534 116 512 166 314 +535 509 305 508 331 +536 322 369 193 170 +537 535 526 581 632 +538 182 314 512 199 +539 497 441 373 540 +540 37 42 46 527 +541 500 209 187 348 +542 312 257 307 243 +543 323 366 281 276 +544 348 420 209 196 +545 366 279 276 272 +546 202 500 186 348 +547 386 406 221 232 +548 64 526 62 489 +549 336 159 185 195 +550 404 24 559 335 +551 404 24 607 559 +552 384 336 552 270 +553 244 240 438 213 +554 244 438 240 250 +555 430 461 620 333 +556 461 333 35 620 +557 61 564 64 334 +558 381 437 47 413 +559 279 277 265 258 +560 279 277 258 274 +561 186 500 181 348 +562 140 510 348 160 +563 377 410 36 350 +564 202 330 236 209 +565 380 345 614 468 +566 99 339 378 106 +567 378 106 418 99 +568 378 448 373 629 +569 194 235 307 182 +570 194 307 166 182 +571 194 307 183 166 +572 353 373 320 378 +573 68 97 83 302 +574 347 496 604 476 +575 161 181 411 373 +576 570 374 400 368 +577 40 38 35 29 +578 364 289 327 528 +579 324 309 319 273 +580 353 378 320 94 +581 358 91 471 375 +582 134 394 302 354 +583 394 149 108 354 +584 172 354 146 149 +585 382 358 471 375 +586 101 382 90 358 +587 651 346 638 390 +588 382 90 100 101 +589 334 594 564 475 +590 369 361 375 322 +591 322 197 369 361 +592 342 325 98 494 +593 325 313 148 342 +594 342 325 375 98 +595 115 369 123 367 +596 342 98 76 494 +597 369 375 576 115 +598 353 512 116 314 +599 336 304 552 296 +600 336 306 304 298 +601 226 514 336 296 +602 108 302 81 394 +603 181 411 373 374 +604 26 440 571 383 +605 26 383 346 440 +606 211 360 308 206 +607 87 74 57 77 +608 358 113 101 382 +609 195 388 336 226 +610 241 233 218 238 +611 155 339 378 353 +612 345 79 468 476 +613 213 316 417 175 +614 387 316 213 175 +615 312 307 262 319 +616 435 485 426 373 +617 435 373 125 485 +618 299 310 306 384 +619 26 425 25 34 +620 118 114 367 434 +621 26 34 25 608 +622 223 222 529 392 +623 527 38 37 35 +624 37 527 46 38 +625 342 123 90 375 +626 342 123 85 90 +627 335 350 33 35 +628 350 461 33 35 +629 85 91 90 123 +630 259 247 308 261 +631 629 628 448 373 +632 633 142 328 128 +633 629 497 628 373 +634 303 61 87 72 +635 236 254 234 331 +636 341 98 325 355 +637 373 570 400 569 +638 398 570 373 569 +639 49 413 527 46 +640 49 46 527 457 +641 49 626 48 527 +642 241 204 243 250 +643 49 527 48 457 +644 392 218 233 238 +645 233 392 238 223 +646 178 198 197 141 +647 198 197 141 369 +648 364 290 287 528 +649 419 381 564 413 +650 92 78 79 59 +651 192 373 314 353 +652 386 406 238 423 +653 367 369 137 391 +654 437 413 419 606 +655 413 437 47 606 +656 239 252 322 255 +657 454 61 339 155 +658 34 466 425 29 +659 221 386 232 240 +660 60 64 489 484 +661 484 65 60 64 +662 212 386 218 221 +663 241 240 386 212 +664 241 205 240 212 +665 607 24 16 470 +666 620 42 37 527 +667 37 333 42 620 +668 95 87 66 69 +669 113 164 382 361 +670 410 30 432 21 +671 371 1 522 458 +672 527 47 43 40 +673 596 425 17 15 +674 393 456 160 311 +675 110 95 87 66 +676 160 311 456 516 +677 512 511 365 166 +678 353 511 365 512 +679 128 144 318 138 +680 341 130 325 308 +681 87 61 57 58 +682 419 58 564 72 +683 414 289 327 364 +684 320 378 435 94 +685 364 528 287 289 +686 212 221 205 240 +687 134 172 149 354 +688 134 172 354 184 +689 319 147 191 307 +690 589 641 606 436 +691 347 79 59 476 +692 345 79 476 92 +693 92 138 144 328 +694 86 92 144 328 +695 32 399 34 38 +696 306 309 336 310 +697 347 604 468 476 +698 347 468 79 476 +699 614 345 79 468 +700 384 310 336 270 +701 439 25 26 422 +702 196 192 314 420 +703 348 420 196 314 +704 132 143 142 318 +705 164 142 143 318 +706 386 406 423 221 +707 35 527 38 40 +708 158 354 96 162 +709 169 302 354 162 +710 334 475 564 363 +711 155 61 303 75 +712 94 353 378 339 +713 224 233 219 212 +714 214 215 204 194 +715 204 243 230 241 +716 204 230 212 241 +717 391 474 369 136 +718 286 588 528 356 +719 35 620 527 47 +720 136 474 361 565 +721 566 526 632 64 +722 490 439 11 14 +723 209 330 420 348 +724 35 527 40 47 +725 76 342 73 98 +726 77 353 102 320 +727 268 308 261 260 +728 167 155 339 378 +729 465 289 385 344 +730 255 308 260 259 +731 335 24 470 33 +732 559 24 470 335 +733 522 1 371 428 +734 347 53 496 54 +735 559 24 607 470 +736 476 347 496 54 +737 312 204 243 307 +738 230 215 243 204 +739 241 218 212 386 +740 241 238 218 386 +741 29 33 28 23 +742 23 335 559 470 +743 297 382 361 341 +744 336 611 185 331 +745 388 185 336 611 +746 353 373 102 320 +747 373 102 314 353 +748 44 527 606 610 +749 74 110 84 353 +750 610 527 606 413 +751 325 341 375 98 +752 369 136 137 391 +753 169 354 342 313 +754 274 366 279 281 +755 281 366 279 276 +756 322 313 206 308 +757 414 289 344 385 +758 114 546 367 434 +759 367 391 434 369 +760 155 163 303 61 +761 47 620 527 44 +762 384 304 552 336 +763 384 310 306 336 +764 99 378 339 94 +765 506 94 378 99 +766 365 353 512 116 +767 378 99 418 506 +768 478 23 559 470 +769 328 86 633 128 +770 265 308 268 266 +771 268 308 263 266 +772 564 419 436 58 +773 460 75 564 65 +774 339 61 99 94 +775 518 564 65 460 +776 643 216 229 392 +777 342 88 76 67 +778 26 422 11 439 +779 26 440 439 571 +780 411 161 373 441 +781 442 467 412 10 +782 350 377 24 33 +783 225 409 217 223 +784 410 377 24 350 +785 24 350 33 335 +786 371 522 523 458 +787 278 324 273 276 +788 273 324 275 276 +789 170 354 172 184 +790 169 179 354 313 +791 607 16 24 580 +792 367 391 137 118 +793 35 620 37 527 +794 548 33 461 333 +795 414 385 344 294 +796 414 289 288 344 +797 65 64 484 454 +798 93 79 78 401 +799 375 382 358 90 +800 413 575 564 594 +801 187 181 368 189 +802 358 375 90 91 +803 275 276 324 323 +804 493 270 323 275 +805 532 323 276 275 +806 324 270 323 415 +807 275 323 324 270 +808 157 331 319 336 +809 454 339 61 338 +810 527 47 507 43 +811 74 87 110 353 +812 61 353 339 155 +813 444 445 618 379 +814 173 133 160 510 +815 352 604 468 347 +816 161 181 373 348 +817 23 335 470 33 +818 181 187 374 373 +819 29 35 28 33 +820 348 187 181 373 +821 562 10 412 447 +822 10 580 503 447 +823 399 351 34 38 +824 515 592 399 32 +825 434 112 637 474 +826 134 82 96 302 +827 224 230 233 212 +828 134 302 96 354 +829 302 354 162 96 +830 376 64 60 564 +831 606 640 589 45 +832 369 137 168 141 +833 113 361 583 136 +834 197 369 168 141 +835 12 7 4 14 +836 510 181 173 171 +837 61 339 353 94 +838 369 154 170 354 +839 404 607 24 21 +840 411 374 578 441 +841 500 186 189 480 +842 535 526 632 566 +843 628 441 497 483 +844 478 23 28 559 +845 28 335 559 23 +846 93 92 78 79 +847 554 473 631 453 +848 198 178 193 141 +849 187 444 209 500 +850 226 388 336 514 +851 287 464 285 528 +852 528 301 285 372 +853 497 629 426 373 +854 394 302 70 82 +855 64 61 454 75 +856 444 587 618 445 +857 467 458 371 523 +858 371 523 520 467 +859 371 520 551 467 +860 385 465 294 292 +861 468 604 345 476 +862 584 517 63 345 +863 176 136 137 369 +864 439 440 18 571 +865 490 26 11 439 +866 324 366 227 357 +867 606 413 419 436 +868 527 48 477 507 +869 527 477 48 457 +870 527 492 48 507 +871 527 626 48 492 +872 134 354 96 158 +873 62 64 489 60 +874 52 57 370 594 +875 326 52 55 564 +876 524 425 17 19 +877 373 441 161 540 +878 373 161 140 540 +879 66 326 55 58 +880 58 326 55 564 +881 310 309 336 270 +882 324 270 336 309 +883 157 336 185 331 +884 181 411 171 161 +885 640 589 641 606 +886 537 557 621 54 +887 282 285 340 288 +888 372 285 288 340 +889 382 100 98 341 +890 502 294 465 292 +891 43 34 351 38 +892 221 240 213 205 +893 438 240 205 213 +894 425 466 524 29 +895 354 302 146 108 +896 435 426 506 629 +897 497 506 426 629 +898 187 181 374 368 +899 517 79 614 345 +900 342 90 73 98 +901 180 141 178 152 +902 178 152 141 168 +903 193 180 141 178 +904 140 161 348 510 +905 9 442 13 362 +906 442 9 13 467 +907 408 505 503 580 +908 607 580 408 16 +909 327 289 414 385 +910 372 284 283 340 +911 359 89 526 566 +912 607 539 478 470 +913 140 373 125 348 +914 328 86 92 517 +915 527 47 44 606 +916 155 163 61 353 +917 367 391 118 434 +918 338 64 61 454 +919 64 338 484 454 +920 359 89 566 338 +921 489 526 566 64 +922 448 192 378 373 +923 350 39 377 33 +924 369 137 176 168 +925 377 350 553 39 +926 325 313 375 341 +927 340 288 625 282 +928 342 313 375 325 +929 524 466 19 20 +930 425 466 19 524 +931 348 395 186 202 +932 610 44 42 45 +933 409 433 217 223 +934 217 433 529 223 +935 582 375 471 115 +936 434 474 637 369 +937 382 375 471 582 +938 98 90 382 375 +939 382 100 90 98 +940 123 105 122 85 +941 122 85 105 80 +942 43 40 34 38 +943 369 474 361 136 +944 469 452 564 460 +945 46 41 527 457 +946 415 366 274 323 +947 191 387 316 438 +948 191 387 156 316 +949 434 391 474 369 +950 502 294 344 465 +951 502 294 292 293 +952 476 59 92 79 +953 306 309 319 336 +954 528 301 464 285 +955 301 282 464 285 +956 208 449 210 379 +957 210 379 220 208 +958 551 520 10 467 +959 359 89 339 106 +960 110 353 365 116 +961 353 511 110 365 +962 118 141 145 152 +963 34 28 466 29 +964 621 347 59 54 +965 59 621 79 347 +966 342 80 122 302 +967 369 123 154 342 +968 123 85 122 342 +969 122 342 85 80 +970 450 349 612 482 +971 564 55 436 413 +972 40 38 29 34 +973 606 641 413 436 +974 28 35 335 33 +975 34 25 32 29 +976 487 548 495 479 +977 187 209 196 348 +978 461 479 430 495 +979 311 513 509 186 +980 395 311 348 186 +981 187 196 209 444 +982 485 540 426 373 +983 21 580 24 447 +984 412 447 21 562 +985 412 562 21 446 +986 447 580 24 10 +987 46 527 610 413 +988 229 392 216 222 +989 323 281 366 274 +990 281 301 274 323 +991 599 625 429 282 +992 608 25 32 34 +993 372 288 284 340 +994 227 324 190 308 +995 373 196 348 187 +996 425 25 34 29 +997 628 448 373 591 +998 591 448 373 398 +999 477 43 41 527 +1000 80 71 81 302 +1001 457 477 41 527 +1002 647 487 430 479 +1003 628 373 497 441 +1004 578 628 441 374 +1005 410 24 335 350 +1006 393 311 160 150 +1007 367 118 137 141 +1008 343 488 356 396 +1009 87 72 61 58 +1010 488 588 356 396 +1011 476 54 59 347 +1012 94 353 61 77 +1013 110 353 87 107 +1014 251 245 322 201 +1015 245 179 322 201 +1016 11 422 486 14 +1017 287 588 464 528 +1018 10 467 412 551 +1019 13 551 412 467 +1020 371 467 551 13 +1021 551 10 8 412 +1022 113 164 361 136 +1023 425 25 15 26 +1024 140 348 125 160 +1025 451 588 528 286 +1026 180 152 145 141 +1027 607 16 539 470 +1028 374 570 400 373 +1029 373 374 556 400 +1030 374 373 556 628 +1031 441 628 578 483 +1032 497 642 418 629 +1033 167 89 106 339 +1034 346 440 390 521 +1035 369 123 342 375 +1036 583 382 498 361 +1037 564 75 72 61 +1038 564 61 64 75 +1039 345 517 79 92 +1040 533 529 223 222 +1041 498 582 576 375 +1042 575 376 609 49 +1043 412 10 8 447 +1044 561 472 549 468 +1045 239 322 252 231 +1046 397 12 4 14 +1047 367 369 434 576 +1048 206 313 322 179 +1049 322 179 313 354 +1050 12 2 4 7 +1051 346 638 26 608 +1052 66 87 57 58 +1053 72 58 564 61 +1054 322 207 231 239 +1055 201 354 322 207 +1056 239 255 322 201 +1057 533 402 529 222 +1058 60 518 564 65 +1059 11 486 12 14 +1060 118 168 141 152 +1061 60 376 564 518 +1062 576 375 582 115 +1063 515 34 399 351 +1064 334 564 64 363 +1065 311 331 150 305 +1066 473 538 597 519 +1067 564 594 575 475 +1068 36 30 432 410 +1069 343 396 356 279 +1070 281 279 356 396 +1071 281 274 301 356 +1072 486 7 14 422 +1073 642 153 585 629 +1074 153 642 628 629 +1075 503 447 8 10 +1076 461 430 620 416 +1077 493 270 275 280 +1078 275 493 532 323 +1079 532 493 282 323 +1080 461 495 430 416 +1081 493 532 280 275 +1082 389 381 47 413 +1083 49 413 626 527 +1084 500 189 186 181 +1085 498 382 582 375 +1086 410 30 24 377 +1087 30 410 36 377 +1088 366 265 279 272 +1089 608 34 32 31 +1090 527 40 43 38 +1091 46 527 41 38 +1092 43 527 38 41 +1093 597 639 7 486 +1094 306 298 336 331 +1095 11 26 15 543 +1096 554 11 15 543 +1097 416 430 620 649 +1098 291 290 364 327 +1099 637 498 375 361 +1100 39 548 33 461 +1101 422 634 25 543 +1102 583 582 382 113 +1103 367 114 118 141 +1104 473 422 11 554 +1105 178 197 168 141 +1106 375 369 123 115 +1107 91 123 115 375 +1108 377 350 36 553 +1109 173 181 516 186 +1110 110 95 107 87 +1111 353 107 163 87 +1112 46 527 42 610 +1113 500 209 348 202 +1114 334 61 564 57 +1115 510 103 140 161 +1116 160 104 140 133 +1117 486 11 473 422 +1118 336 611 331 514 +1119 576 434 637 369 +1120 29 466 524 20 +1121 366 279 265 258 +1122 366 279 258 274 +1123 89 484 338 454 +1124 462 621 568 534 +1125 133 104 140 103 +1126 462 534 568 531 +1127 521 440 390 563 +1128 383 440 563 390 +1129 141 154 170 369 +1130 141 193 369 170 +1131 173 181 510 516 +1132 348 510 181 516 +1133 324 366 276 272 +1134 415 324 366 323 +1135 477 527 507 43 +1136 26 25 440 346 +1137 430 333 42 479 +1138 460 452 564 75 +1139 31 515 32 592 +1140 181 189 187 500 +1141 389 527 413 47 +1142 413 389 626 527 +1143 376 590 49 575 +1144 331 611 185 508 +1145 223 392 407 219 +1146 223 233 392 219 +1147 538 648 597 519 +1148 597 648 538 486 +1149 557 537 568 499 +1150 553 39 461 416 +1151 290 528 451 287 +1152 554 453 332 560 +1153 601 467 458 9 +1154 623 525 535 566 +1155 566 525 535 526 +1156 378 106 431 418 +1157 53 496 352 347 +1158 564 300 419 72 +1159 564 452 300 72 +1160 2 6 7 486 +1161 421 451 528 286 +1162 451 528 588 287 +1163 409 595 433 491 +1164 79 621 78 401 +1165 401 621 78 555 +1166 78 537 555 621 +1167 599 340 282 301 +1168 493 599 282 301 +1169 430 620 42 333 +1170 565 498 112 637 +1171 583 498 112 565 +1172 599 429 536 282 +1173 599 625 459 429 +1174 543 554 332 15 +1175 474 112 637 565 +1176 364 290 528 327 +1177 548 461 479 333 +1178 461 333 430 479 +1179 383 390 346 440 +1180 65 60 64 564 +1181 65 64 75 564 +1182 383 638 346 390 +1183 380 468 614 549 +1184 532 282 276 323 +1185 157 331 504 150 +1186 89 454 338 339 +1187 167 454 89 339 +1188 8 5 10 551 +1189 5 520 10 551 +1190 492 626 545 389 +1191 389 626 545 469 +1192 37 33 35 29 +1193 615 568 499 557 +1194 500 186 480 202 +1195 54 56 53 496 +1196 294 295 291 385 +1197 295 291 385 327 +1198 295 294 292 385 +1199 474 637 361 565 +1200 497 373 426 540 +1201 40 29 28 34 +1202 535 525 581 526 +1203 328 92 79 517 +1204 496 56 352 604 +1205 459 536 646 493 +1206 459 429 624 536 +1207 493 536 280 532 +1208 25 346 26 608 +1209 351 399 41 38 +1210 43 41 38 351 +1211 527 413 47 606 +1212 308 252 322 231 +1213 308 255 322 252 +1214 256 231 252 308 +1215 256 308 259 247 +1216 21 30 24 410 +1217 21 30 562 24 +1218 315 621 555 568 +1219 217 219 223 407 +1220 225 223 219 233 +1221 407 217 529 223 +1222 381 452 300 564 +1223 595 635 433 491 +1224 414 385 291 327 +1225 416 39 461 495 +1226 461 39 548 495 +1227 461 548 479 495 +1228 301 282 281 464 +1229 301 282 285 340 +1230 315 621 568 462 +1231 372 289 288 285 +1232 289 288 285 414 +1233 431 153 106 378 +1234 55 641 589 436 +1235 651 572 638 608 +1236 564 452 72 75 +1237 573 534 567 613 +1238 567 645 600 534 +1239 499 568 577 537 +1240 414 327 291 364 +1241 561 549 614 468 +1242 338 489 566 64 +1243 89 484 489 338 +1244 385 294 465 344 +1245 445 196 444 209 +1246 209 550 444 427 +1247 490 14 11 12 +1248 490 18 14 12 +1249 597 648 486 7 +1250 486 639 7 422 +1251 639 473 597 631 +1252 529 491 616 533 +1253 435 320 125 373 +1254 616 491 529 541 +1255 497 628 642 629 +1256 46 52 413 602 +1257 623 359 566 338 +1258 497 506 629 418 +1259 99 359 623 338 +1260 65 64 454 75 +1261 209 617 550 427 +1262 86 328 144 128 +1263 570 187 374 368 +1264 403 86 633 328 +1265 601 522 458 523 +1266 604 352 472 56 +1267 273 312 319 324 +1268 380 614 63 549 +1269 561 549 63 614 +1270 623 525 566 359 +1271 359 525 566 526 +1272 566 89 526 489 +1273 113 382 358 471 +1274 582 471 382 113 +1275 523 467 458 601 +1276 268 308 260 263 +1277 374 628 556 578 +1278 498 582 382 583 +1279 586 645 534 557 +1280 361 176 369 136 +1281 277 356 274 279 +1282 576 637 375 369 +1283 637 375 369 361 +1284 373 556 569 400 +1285 556 373 569 628 +1286 447 562 24 21 +1287 47 492 527 507 +1288 495 39 548 487 +1289 572 608 651 650 +1290 541 619 542 574 +1291 27 562 21 30 +1292 21 446 562 27 +1293 517 328 614 79 +1294 545 530 622 575 +1295 522 371 523 558 +1296 523 371 520 558 +1297 471 91 115 375 +1298 578 127 628 556 +1299 127 153 628 556 +1300 641 413 55 52 +1301 55 564 436 58 +1302 564 334 57 594 +1303 55 641 436 413 +1304 575 413 49 594 +1305 15 17 596 560 +1306 521 440 563 571 +1307 632 581 62 526 +1308 285 372 301 340 +1309 290 451 528 421 +1310 326 57 564 58 +1311 205 212 241 204 +1312 564 452 469 381 +1313 239 322 207 201 +1314 223 392 529 407 +1315 381 564 413 469 +1316 395 513 311 186 +1317 389 469 413 626 +1318 136 361 583 565 +1319 586 645 567 534 +1320 32 25 608 346 +1321 369 367 137 141 +1322 469 575 545 622 +1323 593 543 634 422 +1324 373 569 628 591 +1325 556 569 153 628 +1326 196 187 373 570 +1327 167 454 339 155 +1328 590 626 575 530 +1329 536 493 282 532 +1330 133 140 160 510 +1331 376 363 64 564 +1332 209 427 444 587 +1333 571 440 563 383 +1334 498 375 576 637 +1335 531 534 568 579 +1336 534 568 557 621 +1337 218 392 643 238 +1338 568 555 577 537 +1339 475 609 363 49 +1340 363 609 475 564 +1341 393 311 150 305 +1342 19 425 17 596 +1343 596 17 603 560 +1344 522 428 371 558 +1345 127 628 497 483 +1346 492 48 545 626 +1347 21 607 24 580 +1348 132 117 318 128 +1349 633 132 547 142 +1350 437 381 419 413 +1351 419 381 437 300 +1352 173 181 186 171 +1353 405 613 600 534 +1354 632 526 62 64 +1355 489 484 64 338 +1356 600 54 53 621 +1357 29 20 28 466 +1358 20 28 466 443 +1359 49 48 626 590 +1360 63 345 614 380 +1361 584 345 63 380 +1362 470 607 559 478 +1363 28 23 22 20 +1364 478 23 22 28 +1365 473 422 554 631 +1366 555 537 568 621 +1367 18 490 14 439 +1368 596 17 19 603 +1369 571 440 18 521 +1370 542 491 616 541 +1371 534 568 615 557 +1372 534 568 579 615 +1373 392 222 229 238 +1374 626 48 530 590 +1375 238 406 229 423 +1376 629 585 642 418 +1377 418 506 629 378 +1378 378 431 629 418 +1379 153 448 628 591 +1380 591 569 628 153 +1381 550 209 500 627 +1382 515 31 32 34 +1383 209 627 550 617 +1384 569 556 153 400 +1385 645 621 557 54 +1386 529 491 533 223 +1387 601 1 458 522 +1388 522 601 1 3 +1389 359 339 99 106 +1390 338 99 359 339 +1391 49 575 626 413 +1392 473 597 631 453 +1393 605 564 518 460 +1394 222 392 402 529 +1395 113 382 583 361 +1396 33 335 28 23 +1397 370 52 594 46 +1398 408 505 580 607 +1399 413 640 602 641 +1400 630 376 564 609 +1401 49 376 609 363 +1402 363 376 609 564 +1403 393 456 311 305 +1404 218 221 386 643 +1405 643 386 423 221 +1406 141 123 369 367 +1407 498 382 375 361 +1408 474 637 369 361 +1409 558 371 520 551 +1410 558 428 371 551 +1411 374 441 411 373 +1412 422 25 26 543 +1413 25 17 15 634 +1414 606 44 610 45 +1415 367 115 369 576 +1416 367 576 546 115 +1417 636 573 567 613 +1418 615 51 579 573 +1419 50 51 615 636 +1420 55 413 564 52 +1421 594 52 413 46 +1422 564 326 52 57 +1423 367 434 546 576 +1424 208 449 379 445 +1425 379 445 544 208 +1426 26 439 440 25 +1427 622 575 605 469 +1428 636 586 567 573 +1429 573 586 567 534 +1430 599 625 340 283 +1431 605 630 518 564 +1432 171 510 181 161 +1433 32 29 38 34 +1434 402 216 392 222 +1435 223 222 392 238 +1436 389 492 527 47 +1437 389 492 626 527 +1438 577 555 78 537 +1439 315 621 401 555 +1440 15 598 634 560 +1441 634 17 15 560 +1442 481 142 328 633 +1443 128 328 144 138 +1444 413 610 640 606 +1445 640 606 610 45 +1446 379 449 444 445 +1447 187 449 196 444 +1448 445 449 444 196 +1449 605 564 460 469 +1450 575 564 605 469 +1451 541 200 619 574 +1452 564 436 419 413 +1453 517 482 63 614 +1454 154 369 141 123 +1455 583 498 565 361 +1456 498 361 637 565 +1457 622 530 630 575 +1458 21 30 432 27 +1459 173 510 160 516 +1460 311 160 348 516 +1461 485 140 540 373 +1462 21 505 580 447 +1463 490 26 439 571 +1464 379 544 220 208 +1465 348 516 181 186 +1466 186 509 311 516 +1467 209 202 627 617 +1468 433 635 529 491 +1469 430 42 620 44 +1470 649 430 620 44 +1471 529 635 541 491 +1472 404 24 410 21 +1473 404 410 24 335 +1474 89 338 359 339 +1475 450 328 482 517 +1476 517 328 482 614 +1477 78 59 537 621 +1478 588 396 281 356 +1479 286 488 588 356 +1480 424 543 593 422 +1481 463 607 408 16 +1482 389 381 413 469 +1483 413 469 575 626 +1484 626 469 575 545 +1485 554 11 543 422 +1486 459 624 646 536 +1487 332 543 593 424 +1488 631 554 424 422 +1489 153 431 629 378 +1490 545 48 530 626 +1491 626 530 545 575 +1492 59 621 78 79 +1493 160 510 348 516 +1494 626 590 575 49 +1495 576 434 112 637 +1496 498 576 112 637 +1497 346 651 638 608 +1498 13 442 412 362 +1499 13 467 412 442 +1500 132 142 633 128 +1501 184 180 172 170 +1502 631 332 424 554 +1503 531 573 579 51 +1504 521 571 563 18 +1505 599 625 282 340 +1506 622 630 605 575 +1507 562 442 362 412 +1508 193 180 170 141 +1509 50 644 636 615 +1510 443 466 20 19 +1511 616 542 533 491 +1512 413 594 564 52 +1513 621 53 600 405 +1514 362 562 446 27 +1515 403 547 321 481 +1516 403 481 321 329 +1517 562 442 412 10 +1518 493 459 536 599 +1519 493 599 536 282 +1520 450 86 328 517 +1521 413 602 610 46 +1522 29 23 28 20 +1523 223 409 433 491 +1524 621 59 537 54 +1525 13 362 412 446 +1526 439 422 11 14 +1527 639 473 631 422 +1528 450 612 584 517 +1529 450 482 612 517 +1530 413 641 602 52 +1531 447 10 24 562 +1532 531 573 534 579 +1533 380 345 468 604 +1534 587 427 444 618 +1535 613 567 600 534 +1536 218 386 238 643 +1537 643 238 423 386 +1538 347 496 352 604 +1539 63 345 517 614 +1540 584 612 63 517 +1541 629 431 585 418 +1542 153 431 585 629 +1543 463 539 478 607 +1544 463 539 607 16 +1545 564 609 475 575 +1546 533 529 402 616 +1547 376 630 564 518 +1548 645 54 600 621 +1549 380 468 472 604 +1550 604 468 472 352 +1551 380 468 549 472 +1552 570 187 373 374 +1553 606 413 641 640 +1554 413 610 602 640 +1555 458 467 13 9 +1556 467 458 13 371 +1557 11 422 26 543 +1558 25 17 425 15 +1559 646 536 280 493 +1560 646 624 280 536 +1561 647 430 44 42 +1562 618 544 220 379 +1563 648 6 486 7 +1564 648 6 538 486 +1565 403 633 547 481 +1566 403 328 633 481 +1567 483 127 628 578 +1568 486 7 12 14 +1569 53 56 352 496 +1570 340 288 284 625 +1571 283 340 284 625 +1572 561 352 472 468 +1573 86 450 328 403 +1574 329 403 481 328 +1575 455 288 284 372 +1576 501 288 284 455 +1577 376 530 575 630 +1578 630 376 609 575 +1579 430 479 42 647 +1580 621 405 600 534 +1581 22 28 20 443 +1582 643 238 229 423 +1583 481 633 547 142 +1584 558 428 551 652 +1585 509 611 331 508 +1586 513 514 331 611 +1587 509 513 331 611 +1588 601 9 1 3 +1589 289 288 344 501 +1590 515 32 399 34 +1591 403 321 349 329 +1592 392 229 643 238 +1593 618 445 544 379 +1594 618 587 544 445 +1595 531 613 534 573 +1596 629 153 448 628 +1597 538 473 597 486 +1598 597 473 639 486 +1599 650 31 608 346 +1600 607 505 580 21 +1601 288 455 289 372 +1602 289 455 288 501 +1603 376 530 590 575 +1604 49 594 475 575 +1605 356 279 281 274 +1606 550 209 444 500 +1607 362 412 446 562 +1608 529 433 491 223 +1609 455 372 284 283 +1610 465 501 455 289 +1611 465 289 344 501 +1612 445 209 444 587 +1613 153 642 127 628 +1614 294 385 291 414 +1615 283 625 459 599 +1616 613 531 51 573 +1617 636 573 613 51 +1618 557 621 568 537 +1619 558 551 520 5 +1620 500 209 202 627 +1621 635 200 541 574 +1622 595 200 635 574 +1623 558 652 551 5 +1624 534 579 573 615 +1625 605 575 630 564 +1626 31 346 32 608 +1627 631 424 639 422 +1628 383 346 638 26 +1629 469 575 564 413 +1630 15 560 332 598 +1631 15 554 332 560 +1632 586 557 534 615 +1633 573 586 534 615 +1634 332 543 598 593 +1635 543 332 598 15 +1636 609 575 564 630 +1637 554 631 332 453 +1638 424 554 543 422 +1639 608 346 651 650 +1640 487 495 430 479 +1641 645 621 534 557 +1642 645 621 600 534 +1643 542 491 541 574 +1644 541 635 574 491 +1645 636 644 586 573 +1646 573 586 615 644 +1647 543 634 598 593 +1648 497 127 642 628 +1649 598 543 15 634 +1650 25 15 543 634 +1651 473 519 597 453 +1652 595 574 635 491 +1653 636 51 615 573 +1654 644 573 636 615 +$EndElements diff --git a/test/user/testdata/shark_41_binary_gmshApp.msh b/test/user/testdata/shark_41_binary_gmshApp.msh new file mode 100644 index 0000000000000000000000000000000000000000..7347169add4a468fa6c09cac527614c874a66c86 GIT binary patch literal 87334 zcmZtucRbba{{a3cGD@g~6iK3z(XcWeAtc#Zkv+5b-t*Xd@4X!yMbVX%(U7b}g(ON! zQW4en^!i-y@9lT{-hTeMdp@1xd7N`Suj_F=uE&K()ymyg(b>(>%wy*{!P8u)xx{x; zY}>YNCy#=Y<^Rvm$cG+w9(GplJIO!%|NHgtS^xX0|7L7o(c6Nk-$tF7dftXY^ooha z(sJmy>5Q?=pJuo%p%Og*lLY6pq%Duhw!;6O_dox;`u}@H9yMo6@`e9*f%xtJ_ptx( zG3EcBP4@r$82prN|9cD-e(Vk`HI@cTi>1T<@2}p4kLj_yu?$#7EE9GQb}x1xmKnPr z%YtRavSANk*|7()hp-%2PV8YU7xoC28+#PXgFS}j#qwc~V^3gDV)?PBumV^?tPoZh zdm4KNdlq{RD}oipiebgE64>)tNvsrB8Y_eSUrV}xk7coPSb6M4tO8aMtAxFTRmNV% zs$j2RRk3PVb*u(f6RU;Q#$LthV0E#2SbeMk_8Qg@YlOXyHO87?O|fQJbF2l{5^IIE z#@b+Qv3A%SSbMAk))DK3b;i12U9oOhcdQ526YGWb#`<7=v3^*8YydV88-xwUhG0Xn zVc2kN1U3>Ig^k9>UA3K13gnf*Cf_;h|#6H6gVV`4%u_M?~ z>=>Bnv_6PPSb{)Hc{e|7cZef38|6u=Ow^97xHx$_ISV}Avb_bRkOM|7w z(qaD>eC)!<^w`~41}r0%3A+co7rPJ3jNOlA!Lnl6um`a0*n`+ZSPm>F_Ar(Udj!jk zJ&NVQ9>elt`LM^aC$J~6{Mb`i0jwZa2rG;|jXi@si#>-G!HQzVu;N$=?0KvtRthVP zmB9k`0#+6)hn2@(#42DFu}auWSY_;GtP1uDRu!v;RmW;zHL+S)ZR}O74ptYdht&heSZAyY))ni9b;o*O zJ+WR`Z>$g27wd=h#|B^nu|e2iYzQ_K8-@+XMqnecQP^l~43>b6#l~Udu?g5jY!WsZ zn}SWnreV{u8Q4s07B(B3gU!X}Ve_#C*g|X(wisK2Eyb2$%dr*MN^BLj8e4;{#nxf# zu?^TpY!jATd^c;8}=sl7PcMRfxV5rgYCq2VeeuQ_8ztydmr0_eSm$4?Zx(C z`>_MqN7%>MC)lUhLF_Z^5cWBC7(0R;#g1Xeu`jR_*q7Kz>=gDD_BHkmb{ac_oyESz z&SBqS=dtgx3)n^M2kb}e67~~z8T%Rg1-pX%ie1Hi!>(b!V}D?OV%M=7*k9O9>=yPn z_7CQ{9IkAVaT-YO6ZtPJk5B3}l*7 z>{;wNtO!;VD~1)vN?^}pC9zUiX{-zuuotkhSUIdb_99jRtB6&?UcxG4FJo1(SFoyB zHLN;T1FMPE!fIo$Vs)^(SUs#h)&P4AYlt<%UdI|^O|Yg|Gpsq*0&9u2!dhc(u(nt` z>^9>1M7+P!g^zUu)bJ7tUopY8;A|U24h38q1Z5NI5q+s ziH*WWV`H!cY%Deo8;`BSiOxW!#rtK8BzRFiwYOuY9!$-=U94+cP|~ktqq5jKXgPB> z^ZI8)cr=@)#*^KG+G8ZN`aDPwF(ndUUETmEHv-EAv|Esfi>7x|c`Z;Bg}LWfmGizTwhPjEy^7;3S$!Ni?IA`JbbLZjs>o@7SfmfeIKQjs3VcK}5%=4!&To zAORW(`F%vG9%#&*e!3MA(Nimf_Z9*qIGRpd7%y1`C+FMt-c})^-XqU%Z%H?Ssl#O@ zcX>S!Ejn@X`6VJMiJMip{i_~gal)6NzCx*}N<{xl_`bQ6l%Y0R3tRX3l?#`e&?ET_ z4PsjZoLdt#?+>Rxo!5jBmJQRzbi?0;P2@m5?D zwkC^&pB`vL$!$Z^8BQ(GqsuNg%@+esXZOEN@o7MVDJyKgq!#dwW~SuHO@^lB<;-^> z4QP*kx}#)234(iPI@4;)fo8>(qDQp>@vf@~%eJ(FvFM6H!c-=tyJ>wR*3~1aXCHbV z2)9DutNy59?rivCKcKGupbn{B4Uu?2XoX7ug3+vs66i@!6>4d$L#>ybs@;o;z?)Ow zSvwj6dd91;aic;fhG0SWwqXui+QR{=fq zeNu;iE!z8rGa@9Q6@-t834Obt3PQWYPKLgzL6h2UYM)A)A;sx@`$ZqKrM7P*h@6HgKfiL_Lzr|t(tc4QZ4fR!^Z?RXbesGc(6#8O*?NdpH552WNcXpQ} zMZq+wGtDjV(KxJe;&u^eFh!|M^p~Nlbxn;sM_Zt(eMhCBM=}JyuUD7gEkiGBC~x@h zXoed#tS_{w39!fH)t2Y=QZ#b5>w$h{Gw3pAM_<{qBh6658jzdDngfk1 zf~;Q)ijn)qjnb18MCf0oJ9joQ9lq`S)!n32gdScv;q4UQ4R0;<@Ow>u8bKnjeVS&DhG1-GE7c>381ma*$%0u#YtPzTP+& zwpgx}1rI+2GY=KzAlb&>XS4?W(S46E2W1=`;aNgafbeuSN^cfW_{igfHf&vch53BI zu;Ax4evwSX7p;Ci#gqsG4wK`i{JHQ@h??s!OC~Di;^?7`ia~)YU!FfV^@a1y>d_{f zX^3-f{vykRIyf{myx-wyCJf9xMcbuQ(5H+Z@d5IEAugJ^YehU8{K_`ps6-_r%eWh7 zOhjCfQy1Ntd%MFxoOLoi$}foTZwFF}I1Wtpihs(0!5k>7j{y&#fk=MzSr?xlv z!L*4QJEe7ffoeyivOGL z^=J|b`uqMNp(ztO=aU#nRRm;sb!>m2dL!5h@_tI`EP(`9Mr{Wc0-}`?4p}K7pU1h0ujkoX{mA^Kv&Qr>bOd&#mRE+ZKWTEY5fHEi@w?npnFP+GH4V zQ1_Np3r92`2HW@Bw4oDR%fTUSsc>f7Ro6Kd@_D>4dGy?CMdQ<%Afvj;RqGLgCKrF| z>%^8r7@e30!$vOfeGRrXPYFfokxfmWH4TXNkI~E8fn+G(Us2&C6N0WYx@f(PNJFE! z?>VX#V}L3}A=if{1krlmuRL+R0fKY{ul{MvhaATusezhcl*TghRl2_kUHjd){(iX- za%1{`v1$dQPmg1|TVm=UZ|tkuT2nY2c-A4ql^BRjblptYe$^mGf!%uM8<}tV6R zJP>({jE2A7Rfk5?=`0UkPlY!u`^2q?eu(X9&7$~~AXG0EO4P28h1rgA^BJ`ObY}Bj z5QiH#N`DsgzWhxHjHz`|dNKQ>(cR2Gd_|RzaC~|9U10)Ty|bGpX`n0<6ytJ%e7;JVz!ybL0r_kw zU*ni=41~hv6Y|6zY_2G5n3~0lrU|{%HdL5ALV&-Ycmt*roY4msmq_b`YB-bSxO3u3 zC^*tJ?NimYM^BRwsam}j!mE<`zn?0GM~8SluWQ?*x=WHg_C3ug?8ynEkNz?6lh*n3 zSv`C7t044~Ml}(wOFG|m$c%#5V|>XMzuTa+ePZo*4XVN7O%7VuFNXY!r^OaFtWm+9 zimqrDkDP+fc{hbWre$iKttodPu|TO?J_U6H@Q%Ro|`rnKak4?6Dj2> zk111BB$1qZ(5DgA>|fkPdpQt%Bi=PSyBZ^<<(Gq6yNM`;b7)TXK{VuS)M@i&>!Yzt z6#64|W$3@KU~e%TyvZ!^Btj2ml}HYsyjX(5CF@L^cBR7A65Bf&HoE9NluzGfAfir& zIGW4%5@8}ka)Rd16{HxzXWhlth!zO(t%>RhK$)<*Mdfo5Jykf9t74ji%#;M)ytK`Q zNjpBivkVu|f8G23EI6zD+?h%(4TA03K0iQ=h;OZEGBPd&E{ygiIIL#@`;c_AbD2J% zuyYpAJxYPbw|l6))*qbY*e{(3Is?Y`mv{GfWTQ52uKjHvQ((=|^_RjEQPB20*D9&p zjPeaAJk&~yVex9JTL`}tsAL&TA1tgu`TcyTc%}qmr_?P5JU>o1;a#wM zqX_mS*V(=iQ-?gp1I0mRc_<^Mved>d0mSvpCoafnLTs1Wr$L@HIC_l7nO;5s2tS7( zxu4Ynwm?&EiM3YrxRe-IN|Oi!(S03O|3S5`miIZ8J^G(m}$L;jELgIS^?7 za@#&3qPBYPq{78;@Hk-SyeHipIRE6 zqY#V6*MbwjE+|xQ%tKtT*9HWtL`Fas?#k{>(`z9G=&s$L* zWpD(F&pmO^8i|PQNr|*VofrHunP8wAas>yygh#9F3jZKB7|zZ7iT}`1_yrc4qiP(LhsGClBzDG zfHYxS;-rQPmyUT_akfYY`wIcv1SS zw>$XDFthL$BEvwx#MP_fq8I!(EqRiRqy~dN z?PHaXkunLF?92>{`BS26! zz<<5b2eRa4r=JuyqJ0ZV)bb{7zLJa_tSR0!N#IHj+y z)r<`8PqInQMgqyk@{x6FD17eaqZ8ar1#)9eW%3IFJHmmTj_zSVeS$+%k)jT<)^(C2 zr82lIT(5d!C>%87qqW8#6`?!h5@sCS6>v}e^l`{aHZ9g0{(Oj) zGd&yuQy;n(yyja`A8BgD&oUeAlEcU&QzV3H{rRh$KtzI98vPTcf`F8EXqS~#B$y?u zAB|CKK?J)Db%mKi7!axT>6eIt177Y|T!}>F_&ewQ{pCmqITTLizdagAo4Y!~Xt1oMwR#!s_snX_x>@tsPu@ z=qix+-ZS(<-`s&9YdSx~9S069zGcP7av=Ul{OsE#XBg|yr}?242iE%kBJx6{PRXYi z;~N0{iN>~c32`vjrP+Uk#~r;ADynB|tOP471%tk>Ex9c)-DjBU3qhCI5h!cBklh(Ph@}wU($8`<#O&C=`SeK(Fp#`q+VDcyZamMgW4rqwDxjN9)LGUr z4}#JtHsuqOVPIjuy7X|!|66#+rCRr5jyw9KB}w+Tt;xX2 zc41wkGy^1=9zeoRKUnrS&AR`=`XTZv1scQOcx}1WpiH*?Vb({= zfai$l@1XG%7%tvzrTUzRZq=1=eljNapOHZnY$sE}TJ-3fjP?=;di-*QjevbYT%8m5;e0z8d%3zTz{pQhO}

GQCIJ_1a)|{^1w5vn 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%0A<)?x6F&@uz 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 AWB>pF literal 0 HcmV?d00001 diff --git a/test/user/testdata/shark_41_binary_gmshApp.xml b/test/user/testdata/shark_41_binary_gmshApp.xml new file mode 100644 index 00000000..9261a2f0 --- /dev/null +++ b/test/user/testdata/shark_41_binary_gmshApp.xml @@ -0,0 +1,25 @@ + + diff --git a/test/user/user_flex_test.cc b/test/user/user_flex_test.cc index 2552c9bd..aaaa7364 100644 --- a/test/user/user_flex_test.cc +++ b/test/user/user_flex_test.cc @@ -227,5 +227,177 @@ TEST_F(UserFlexTest, CreateBVHSuccess) { mj_deleteData(d); } +TEST_F(UserFlexTest, LoadMSHBinaryGMSH_41_Success) { + const std::string xml_path = + GetTestDataFilePath("user/testdata/shark_41_binary_gmshApp.xml"); + std::array error; + mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size()); + mjData* d = mj_makeData(m); + EXPECT_THAT(m, NotNull()) << error.data(); + EXPECT_EQ(m->nflexvert, 652); + EXPECT_EQ(m->nflexelem, 1654); + mj_step(m, d); + mj_deleteModel(m); + mj_deleteData(d); +} + +TEST_F(UserFlexTest, LoadMSHBinaryGMSH_22_Success) { + const std::string xml_path = + GetTestDataFilePath("user/testdata/shark_22_binary_gmshApp.xml"); + std::array error; + mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size()); + mjData* d = mj_makeData(m); + EXPECT_THAT(m, NotNull()) << error.data(); + EXPECT_EQ(m->nflexvert, 644); + EXPECT_EQ(m->nflexelem, 1635); + mj_step(m, d); + mj_deleteModel(m); + mj_deleteData(d); +} + +TEST_F(UserFlexTest, LoadMSHBinaryFTETWILD_22_Success) { + const std::string xml_path = + GetTestDataFilePath("user/testdata/shark_22_binary_fTetWild.xml"); + std::array error; + mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size()); + mjData* d = mj_makeData(m); + EXPECT_THAT(m, NotNull()) << error.data(); + EXPECT_EQ(m->nflexvert, 644); + EXPECT_EQ(m->nflexelem, 1635); + mj_step(m, d); + mj_deleteModel(m); + mj_deleteData(d); +} + +TEST_F(UserFlexTest, LoadMSHASCIIGMSH_41_Success) { + const std::string xml_path = + GetTestDataFilePath("user/testdata/shark_41_ascii_gmshApp.xml"); + std::array error; + mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size()); + mjData* d = mj_makeData(m); + EXPECT_THAT(m, NotNull()) << error.data(); + EXPECT_EQ(m->nflexvert, 652); + EXPECT_EQ(m->nflexelem, 1654); + mj_step(m, d); + mj_deleteModel(m); + mj_deleteData(d); +} + +TEST_F(UserFlexTest, LoadMSHASCIIGMSH_22_Success) { + const std::string xml_path = + GetTestDataFilePath("user/testdata/shark_22_ascii_gmshApp.xml"); + std::array error; + mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size()); + mjData* d = mj_makeData(m); + EXPECT_THAT(m, NotNull()) << error.data(); + EXPECT_EQ(m->nflexvert, 652); + EXPECT_EQ(m->nflexelem, 1654); + mj_step(m, d); + mj_deleteModel(m); + mj_deleteData(d); +} + +TEST_F(UserFlexTest, LoadMSHASCIIFTETWILD_22_Success) { + const std::string xml_path = + GetTestDataFilePath("user/testdata/shark_22_ascii_fTetWild.xml"); + std::array error; + mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size()); + mjData* d = mj_makeData(m); + EXPECT_THAT(m, NotNull()) << error.data(); + EXPECT_EQ(m->nflexvert, 652); + EXPECT_EQ(m->nflexelem, 1654); + mj_step(m, d); + mj_deleteModel(m); + mj_deleteData(d); +} + +TEST_F(UserFlexTest, LoadMSHASCII_41_MissingNodeHeader_Fail) { + const std::string xml_path = + GetTestDataFilePath( + "user/testdata/malformed_shark_41_ascii_missing_node_header.xml"); + std::array error; + mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size()); + EXPECT_THAT(error.data(), HasSubstr( + "XML Error: Error: All nodes must be in single block")); + mj_deleteModel(m); +} + +TEST_F(UserFlexTest, LoadMSHASCII_41_MissingNodeIndex_Fail) { + const std::string xml_path = + GetTestDataFilePath( + "user/testdata/malformed_shark_41_ascii_missing_node_index.xml"); + std::array error; + mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size()); + EXPECT_THAT(error.data(), HasSubstr( + "XML Error: Element size must be a multiple of dim+1")); + mj_deleteModel(m); +} + +TEST_F(UserFlexTest, LoadMSHASCII_41_MissingElementHeader_Fail) { + const std::string xml_path = + GetTestDataFilePath( + "user/testdata/malformed_shark_41_ascii_missing_element_header.xml"); + std::array error; + mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size()); + EXPECT_THAT(error.data(), HasSubstr( + "XML Error: Error: All elements must be in single block")); + mj_deleteModel(m); +} + +TEST_F(UserFlexTest, LoadMSHASCII_41_MissingElement_Fail) { + const std::string xml_path = + GetTestDataFilePath( + "user/testdata/malformed_shark_41_ascii_missing_element.xml"); + std::array error; + mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size()); + EXPECT_THAT(error.data(), HasSubstr( + "XML Error: Error: Error reading Elements")); + mj_deleteModel(m); +} + +TEST_F(UserFlexTest, LoadMSHASCII_22_MissingNumNodes_Fail) { + const std::string xml_path = + GetTestDataFilePath( + "user/testdata/malformed_shark_22_ascii_missing_num_nodes.xml"); + std::array error; + mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size()); + EXPECT_THAT(error.data(), HasSubstr( + "XML Error: Element size must be a multiple of dim+1")); + mj_deleteModel(m); +} + +TEST_F(UserFlexTest, LoadMSHASCII_22_MissingNode_Fail) { + const std::string xml_path = + GetTestDataFilePath( + "user/testdata/malformed_shark_22_ascii_missing_node.xml"); + std::array error; + mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size()); + EXPECT_THAT(error.data(), HasSubstr( + "XML Error: Error: Error reading node tags")); + mj_deleteModel(m); +} + +TEST_F(UserFlexTest, LoadMSHASCII_22_MissingNumElements_Fail) { + const std::string xml_path = + GetTestDataFilePath( + "user/testdata/malformed_shark_22_ascii_missing_num_elements.xml"); + std::array error; + mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size()); + EXPECT_THAT(error.data(), HasSubstr( + "XML Error: Element size must be a multiple of dim+1")); + mj_deleteModel(m); +} + +TEST_F(UserFlexTest, LoadMSHASCII_22_MissingElement_Fail) { + const std::string xml_path = + GetTestDataFilePath( + "user/testdata/malformed_shark_22_ascii_missing_element.xml"); + std::array error; + mjModel* m = mj_loadXML(xml_path.c_str(), 0, error.data(), error.size()); + EXPECT_THAT(error.data(), HasSubstr( + "XML Error: Error: Error reading Elements")); + mj_deleteModel(m); +} + } // namespace } // namespace mujoco diff --git a/test/xml/xml_native_writer_test.cc b/test/xml/xml_native_writer_test.cc index c9ca0a09..cf48889b 100644 --- a/test/xml/xml_native_writer_test.cc +++ b/test/xml/xml_native_writer_test.cc @@ -1204,6 +1204,7 @@ TEST_F(XMLWriterTest, WriteReadCompare) { if (absl::StrContains(p.path().string(), "malformed_") || absl::StrContains(p.path().string(), "touch_grid") || absl::StrContains(p.path().string(), "gmsh_") || + absl::StrContains(p.path().string(), "shark_") || absl::StrContains(p.path().string(), "cow")) { continue; } From e6bf6fc327bf5201ddf64583e3ddf35116e34f87 Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Wed, 27 Mar 2024 06:34:25 -0700 Subject: [PATCH 41/51] Fix a bug in the ellipsoid SDF gradient. PiperOrigin-RevId: 619512430 Change-Id: Ia4c2f01d1767f36313177334ceda02d3a9e2e495 --- src/engine/engine_collision_sdf.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/engine/engine_collision_sdf.c b/src/engine/engine_collision_sdf.c index 79d97e03..5723dafb 100644 --- a/src/engine/engine_collision_sdf.c +++ b/src/engine/engine_collision_sdf.c @@ -140,9 +140,18 @@ static void geomGradient(mjtNum gradient[3], const mjModel* m, const mjData* d, b[2] = a[2] / size[2]; mjtNum k0 = mju_norm3(a); mjtNum k1 = mju_norm3(b); - gradient[0] = a[0]*(2.*k0 - 1.) / k1 + k0*(k0 - 1.) * b[0]/(k1*k1); - gradient[1] = a[1]*(2.*k0 - 1.) / k1 + k0*(k0 - 1.) * b[1]/(k1*k1); - gradient[2] = a[2]*(2.*k0 - 1.) / k1 + k0*(k0 - 1.) * b[2]/(k1*k1); + mjtNum invK0 = 1. / k0; + mjtNum invK1 = 1. / k1; + mjtNum gk0[3] = {b[0]*invK0, b[1]*invK0, b[2]*invK0}; + mjtNum gk1[3] = {b[0]*invK1/(size[0]*size[0]), + b[1]*invK1/(size[1]*size[1]), + b[2]*invK1/(size[2]*size[2])}; + mjtNum df_dk0 = (2.*k0 - 1.) * invK1; + mjtNum df_dk1 = k0*(k0 - 1.) * invK1 * invK1; + gradient[0] = gk0[0]*df_dk0 - gk1[0]*df_dk1; + gradient[1] = gk0[1]*df_dk0 - gk1[1]*df_dk1; + gradient[2] = gk0[2]*df_dk0 - gk1[2]*df_dk1; + mju_normalize3(gradient); break; case mjGEOM_CYLINDER: c = mju_sqrt(x[0]*x[0]+x[1]*x[1]); From dfe2b7537893f1a3f2c2135a6109e07fbd9054a7 Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Wed, 27 Mar 2024 07:36:43 -0700 Subject: [PATCH 42/51] Convert mjElement to struct rather than opaque pointer. By making mjElement the parent of mjCBase, mjCModel, and mjCDef, this CL enables safer casting using static_cast instead of reinterpret_cast and C-style casting. PiperOrigin-RevId: 619526291 Change-Id: Ifa2b4bd3ecd95bade61f41a7005c62212f456c00 --- src/user/user_api.cc | 144 +++++++++++++++++------------------ src/user/user_api.h | 70 +++++++++-------- src/user/user_composite.cc | 10 +-- src/user/user_flexcomp.cc | 6 +- src/user/user_mesh.cc | 17 +++-- src/user/user_model.cc | 11 +-- src/user/user_model.h | 2 +- src/user/user_objects.cc | 94 ++++++++++++++--------- src/user/user_objects.h | 4 +- src/xml/xml_native_writer.cc | 4 +- 10 files changed, 199 insertions(+), 163 deletions(-) diff --git a/src/user/user_api.cc b/src/user/user_api.cc index a0ca98e6..6220d98a 100644 --- a/src/user/user_api.cc +++ b/src/user/user_api.cc @@ -58,7 +58,7 @@ mjSpec* mjs_createSpec() { // copy model mjSpec* mjs_copySpec(const mjSpec* s) { - mjCModel* modelC = new mjCModel(*reinterpret_cast(s->element)); + mjCModel* modelC = new mjCModel(*static_cast(s->element)); return &modelC->spec; } @@ -66,7 +66,7 @@ mjSpec* mjs_copySpec(const mjSpec* s) { // copy back model void mjs_copyBack(mjSpec* s, const mjModel* m) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); modelC->CopyBack(m); } @@ -74,7 +74,7 @@ void mjs_copyBack(mjSpec* s, const mjModel* m) { // compile model mjModel* mjs_compile(mjSpec* s, const mjVFS* vfs) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); return modelC->Compile(vfs); } @@ -83,8 +83,8 @@ mjModel* mjs_compile(mjSpec* s, const mjVFS* vfs) { // attach body to a frame of the parent int mjs_attachBody(mjsFrame* parent, const mjsBody* child, const char* prefix, const char* suffix) { - mjCFrame* frame_parent = reinterpret_cast(parent->element); - mjCBody* child_body = reinterpret_cast(child->element); + mjCFrame* frame_parent = static_cast(parent->element); + mjCBody* child_body = static_cast(child->element); *frame_parent += std::string(prefix) + *child_body + std::string(suffix); return 0; } @@ -93,7 +93,7 @@ int mjs_attachBody(mjsFrame* parent, const mjsBody* child, // get error message from model const char* mjs_getError(mjSpec* s) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); return modelC->GetError().message; } @@ -101,7 +101,7 @@ const char* mjs_getError(mjSpec* s) { // check if model has warnings int mjs_isWarning(mjSpec* s) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); return modelC->GetError().warning; } @@ -109,7 +109,7 @@ int mjs_isWarning(mjSpec* s) { // delete model void mjs_deleteSpec(mjSpec* s) { - mjCModel* model = reinterpret_cast(s->element); + mjCModel* model = static_cast(s->element); delete model; } @@ -117,8 +117,8 @@ void mjs_deleteSpec(mjSpec* s) { // add child body to body, return child spec mjsBody* mjs_addBody(mjsBody* bodyspec, mjsDefault* defspec) { - mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; - mjCBody* body = reinterpret_cast(bodyspec->element)->AddBody(def); + mjCDef* def = defspec ? static_cast(defspec->element) : 0; + mjCBody* body = static_cast(bodyspec->element)->AddBody(def); return &body->spec; } @@ -126,8 +126,8 @@ mjsBody* mjs_addBody(mjsBody* bodyspec, mjsDefault* defspec) { // add site to body, return site spec mjsSite* mjs_addSite(mjsBody* bodyspec, mjsDefault* defspec) { - mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; - mjCBody* body = reinterpret_cast(bodyspec->element); + mjCDef* def = defspec ? static_cast(defspec->element) : 0; + mjCBody* body = static_cast(bodyspec->element); mjCSite* site = body->AddSite(def); return &site->spec; } @@ -136,8 +136,8 @@ mjsSite* mjs_addSite(mjsBody* bodyspec, mjsDefault* defspec) { // add joint to body mjsJoint* mjs_addJoint(mjsBody* bodyspec, mjsDefault* defspec) { - mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; - mjCBody* body = reinterpret_cast(bodyspec->element); + mjCDef* def = defspec ? static_cast(defspec->element) : 0; + mjCBody* body = static_cast(bodyspec->element); mjCJoint* joint = body->AddJoint(def); return &joint->spec; } @@ -146,7 +146,7 @@ mjsJoint* mjs_addJoint(mjsBody* bodyspec, mjsDefault* defspec) { // add free joint to body mjsJoint* mjs_addFreeJoint(mjsBody* bodyspec) { - mjCBody* body = reinterpret_cast(bodyspec->element); + mjCBody* body = static_cast(bodyspec->element); mjCJoint* joint = body->AddFreeJoint(); return &joint->spec; } @@ -155,8 +155,8 @@ mjsJoint* mjs_addFreeJoint(mjsBody* bodyspec) { // add geom to body mjsGeom* mjs_addGeom(mjsBody* bodyspec, mjsDefault* defspec) { - mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; - mjCBody* body = reinterpret_cast(bodyspec->element); + mjCDef* def = defspec ? static_cast(defspec->element) : 0; + mjCBody* body = static_cast(bodyspec->element); mjCGeom* geom = body->AddGeom(def); return &geom->spec; } @@ -165,8 +165,8 @@ mjsGeom* mjs_addGeom(mjsBody* bodyspec, mjsDefault* defspec) { // add camera to body mjsCamera* mjs_addCamera(mjsBody* bodyspec, mjsDefault* defspec) { - mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; - mjCBody* body = reinterpret_cast(bodyspec->element); + mjCDef* def = defspec ? static_cast(defspec->element) : 0; + mjCBody* body = static_cast(bodyspec->element); mjCCamera* camera = body->AddCamera(def); return &camera->spec; } @@ -175,8 +175,8 @@ mjsCamera* mjs_addCamera(mjsBody* bodyspec, mjsDefault* defspec) { // add light to body mjsLight* mjs_addLight(mjsBody* bodyspec, mjsDefault* defspec) { - mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; - mjCBody* body = reinterpret_cast(bodyspec->element); + mjCDef* def = defspec ? static_cast(defspec->element) : 0; + mjCBody* body = static_cast(bodyspec->element); mjCLight* light = body->AddLight(def); return &light->spec; } @@ -185,7 +185,7 @@ mjsLight* mjs_addLight(mjsBody* bodyspec, mjsDefault* defspec) { // add flex to model mjsFlex* mjs_addFlex(mjSpec* s) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); mjCFlex* flex = modelC->AddFlex(); return &flex->spec; } @@ -196,9 +196,9 @@ mjsFlex* mjs_addFlex(mjSpec* s) { mjsFrame* mjs_addFrame(mjsBody* bodyspec, mjsFrame* parentframe) { mjCFrame* parentframeC = 0; if (parentframe) { - parentframeC = reinterpret_cast(parentframe->element); + parentframeC = static_cast(parentframe->element); } - mjCBody* body = reinterpret_cast(bodyspec->element); + mjCBody* body = static_cast(bodyspec->element); mjCFrame* frameC = body->AddFrame(parentframeC); frameC->SetParent(body); return &frameC->spec; @@ -208,8 +208,8 @@ mjsFrame* mjs_addFrame(mjsBody* bodyspec, mjsFrame* parentframe) { // add mesh to model mjsMesh* mjs_addMesh(mjSpec* s, mjsDefault* defspec) { - mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; - mjCModel* modelC = reinterpret_cast(s->element); + mjCDef* def = defspec ? static_cast(defspec->element) : 0; + mjCModel* modelC = static_cast(s->element); mjCMesh* mesh = modelC->AddMesh(def); return &mesh->spec; } @@ -218,7 +218,7 @@ mjsMesh* mjs_addMesh(mjSpec* s, mjsDefault* defspec) { // add height field to model mjsHField* mjs_addHField(mjSpec* s) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); mjCHField* heightField = modelC->AddHField(); return &heightField->spec; } @@ -227,7 +227,7 @@ mjsHField* mjs_addHField(mjSpec* s) { // add skin to model mjsSkin* mjs_addSkin(mjSpec* s) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); mjCSkin* skin = modelC->AddSkin(); return &skin->spec; } @@ -236,7 +236,7 @@ mjsSkin* mjs_addSkin(mjSpec* s) { // add texture to model mjsTexture* mjs_addTexture(mjSpec* s) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); mjCTexture* texture = modelC->AddTexture(); return &texture->spec; } @@ -245,8 +245,8 @@ mjsTexture* mjs_addTexture(mjSpec* s) { // add material to model mjsMaterial* mjs_addMaterial(mjSpec* s, mjsDefault* defspec) { - mjCModel* modelC = reinterpret_cast(s->element); - mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; + mjCModel* modelC = static_cast(s->element); + mjCDef* def = defspec ? static_cast(defspec->element) : 0; mjCMaterial* material = modelC->AddMaterial(def); return &material->spec; } @@ -255,8 +255,8 @@ mjsMaterial* mjs_addMaterial(mjSpec* s, mjsDefault* defspec) { // add pair to model mjsPair* mjs_addPair(mjSpec* s, mjsDefault* defspec) { - mjCModel* modelC = reinterpret_cast(s->element); - mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; + mjCModel* modelC = static_cast(s->element); + mjCDef* def = defspec ? static_cast(defspec->element) : 0; mjCPair* pair = modelC->AddPair(def); return &pair->spec; } @@ -265,7 +265,7 @@ mjsPair* mjs_addPair(mjSpec* s, mjsDefault* defspec) { // add pair exclusion to model mjsExclude* mjs_addExclude(mjSpec* s) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); mjCBodyPair* bodypair = modelC->AddExclude(); return &bodypair->spec; } @@ -274,8 +274,8 @@ mjsExclude* mjs_addExclude(mjSpec* s) { // add equality to model mjsEquality* mjs_addEquality(mjSpec* s, mjsDefault* defspec) { - mjCModel* modelC = reinterpret_cast(s->element); - mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; + mjCModel* modelC = static_cast(s->element); + mjCDef* def = defspec ? static_cast(defspec->element) : 0; mjCEquality* equality = modelC->AddEquality(def); return &equality->spec; } @@ -284,8 +284,8 @@ mjsEquality* mjs_addEquality(mjSpec* s, mjsDefault* defspec) { // add tendon to model mjsTendon* mjs_addTendon(mjSpec* s, mjsDefault* defspec) { - mjCModel* modelC = reinterpret_cast(s->element); - mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; + mjCModel* modelC = static_cast(s->element); + mjCDef* def = defspec ? static_cast(defspec->element) : 0; mjCTendon* tendon = modelC->AddTendon(def); return &tendon->spec; } @@ -294,7 +294,7 @@ mjsTendon* mjs_addTendon(mjSpec* s, mjsDefault* defspec) { // wrap site using tendon MJAPI mjsWrap* mjs_wrapSite(mjsTendon* tendonspec, const char* name) { - mjCTendon* tendon = reinterpret_cast(tendonspec->element); + mjCTendon* tendon = static_cast(tendonspec->element); tendon->WrapSite(name); return &tendon->path.back()->spec; } @@ -303,7 +303,7 @@ MJAPI mjsWrap* mjs_wrapSite(mjsTendon* tendonspec, const char* name) { // wrap geom using tendon mjsWrap* mjs_wrapGeom(mjsTendon* tendonspec, const char* name, const char* sidesite) { - mjCTendon* tendon = reinterpret_cast(tendonspec->element); + mjCTendon* tendon = static_cast(tendonspec->element); tendon->WrapGeom(name, sidesite); return &tendon->path.back()->spec; } @@ -312,7 +312,7 @@ mjsWrap* mjs_wrapGeom(mjsTendon* tendonspec, const char* name, const char* sides // wrap joint using tendon mjsWrap* mjs_wrapJoint(mjsTendon* tendonspec, const char* name, double coef) { - mjCTendon* tendon = reinterpret_cast(tendonspec->element); + mjCTendon* tendon = static_cast(tendonspec->element); tendon->WrapJoint(name, coef); return &tendon->path.back()->spec; } @@ -321,7 +321,7 @@ mjsWrap* mjs_wrapJoint(mjsTendon* tendonspec, const char* name, double coef) { // wrap pulley using tendon mjsWrap* mjs_wrapPulley(mjsTendon* tendonspec, double divisor) { - mjCTendon* tendon = reinterpret_cast(tendonspec->element); + mjCTendon* tendon = static_cast(tendonspec->element); tendon->WrapPulley(divisor); return &tendon->path.back()->spec; } @@ -330,8 +330,8 @@ mjsWrap* mjs_wrapPulley(mjsTendon* tendonspec, double divisor) { // add actuator to model mjsActuator* mjs_addActuator(mjSpec* s, mjsDefault* defspec) { - mjCModel* modelC = reinterpret_cast(s->element); - mjCDef* def = defspec ? reinterpret_cast(defspec->element) : 0; + mjCModel* modelC = static_cast(s->element); + mjCDef* def = defspec ? static_cast(defspec->element) : 0; mjCActuator* actuator = modelC->AddActuator(def); return &actuator->spec; } @@ -340,7 +340,7 @@ mjsActuator* mjs_addActuator(mjSpec* s, mjsDefault* defspec) { // add sensor to model mjsSensor* mjs_addSensor(mjSpec* s) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); mjCSensor* sensor = modelC->AddSensor(); return &sensor->spec; } @@ -349,7 +349,7 @@ mjsSensor* mjs_addSensor(mjSpec* s) { // add numeric to model mjsNumeric* mjs_addNumeric(mjSpec* s) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); mjCNumeric* numeric = modelC->AddNumeric(); return &numeric->spec; } @@ -358,7 +358,7 @@ mjsNumeric* mjs_addNumeric(mjSpec* s) { // add text to model mjsText* mjs_addText(mjSpec* s) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); mjCText* text = modelC->AddText(); return &text->spec; } @@ -367,7 +367,7 @@ mjsText* mjs_addText(mjSpec* s) { // add tuple to model mjsTuple* mjs_addTuple(mjSpec* s) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); mjCTuple* tuple = modelC->AddTuple(); return &tuple->spec; } @@ -376,7 +376,7 @@ mjsTuple* mjs_addTuple(mjSpec* s) { // add keyframe to model mjsKey* mjs_addKey(mjSpec* s) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); mjCKey* key = modelC->AddKey(); return &key->spec; } @@ -385,9 +385,9 @@ mjsKey* mjs_addKey(mjSpec* s) { // add plugin to model mjsPlugin* mjs_addPlugin(mjSpec* s) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); mjCPlugin* plugin = modelC->AddPlugin(); - plugin->spec.instance = (mjElement)plugin; + plugin->spec.instance = static_cast(plugin); return &plugin->spec; } @@ -395,7 +395,7 @@ mjsPlugin* mjs_addPlugin(mjSpec* s) { // add default to model mjsDefault* mjs_addDefault(mjSpec* s, const char* classname, int parentid, int* id) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); *id = (int)modelC->defaults.size(); mjCDef* def = modelC->AddDef(classname, parentid); if (def) { @@ -409,21 +409,21 @@ mjsDefault* mjs_addDefault(mjSpec* s, const char* classname, int parentid, int* // get objects mjSpec* mjs_getSpec(mjsBody* body) { - return &(reinterpret_cast(body->element)->model->spec); + return &(static_cast(body->element)->model->spec); } // get default -mjsDefault* mjs_getDefault(mjElement element) { - return &(reinterpret_cast(element)->def->spec); +mjsDefault* mjs_getDefault(mjElement* element) { + return &(static_cast(element)->def->spec); } // Find default with given name in model. mjsDefault* mjs_findDefault(mjSpec* s, const char* classname) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); mjCDef* cdef = modelC->FindDef(classname); if (!cdef) { return nullptr; @@ -435,7 +435,7 @@ mjsDefault* mjs_findDefault(mjSpec* s, const char* classname) { // get default[0] from model mjsDefault* mjs_getSpecDefault(mjSpec* s) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); mjCDef* def = modelC->defaults[0]; if (!def) { return nullptr; @@ -447,7 +447,7 @@ mjsDefault* mjs_getSpecDefault(mjSpec* s) { // find body in model by name mjsBody* mjs_findBody(mjSpec* s, const char* name) { - mjCModel* model = reinterpret_cast(s->element); + mjCModel* model = static_cast(s->element); mjCBase* body = 0; if (model->IsCompiled()) { body = model->FindObject(mjOBJ_BODY, std::string(name)); // fast lookup @@ -461,7 +461,7 @@ mjsBody* mjs_findBody(mjSpec* s, const char* name) { // find child of a body by name mjsBody* mjs_findChild(mjsBody* bodyspec, const char* name) { - mjCBody* body = reinterpret_cast(bodyspec->element); + mjCBody* body = static_cast(bodyspec->element); mjCBase* child = body->FindObject(mjOBJ_BODY, std::string(name)); return child ? &(static_cast(child)->spec) : nullptr; } @@ -470,7 +470,7 @@ mjsBody* mjs_findChild(mjsBody* bodyspec, const char* name) { // find mesh by name mjsMesh* mjs_findMesh(mjSpec* s, const char* name) { - mjCModel* model = reinterpret_cast(s->element); + mjCModel* model = static_cast(s->element); mjCMesh* mesh = (mjCMesh*)model->FindObject(mjOBJ_MESH, std::string(name)); return mesh ? &(static_cast(mesh)->spec) : nullptr; } @@ -479,7 +479,7 @@ mjsMesh* mjs_findMesh(mjSpec* s, const char* name) { // find frame by name mjsFrame* mjs_findFrame(mjSpec* s, const char* name) { - mjCModel* model = reinterpret_cast(s->element); + mjCModel* model = static_cast(s->element); mjCFrame* frame = (mjCFrame*)model->FindFrame(model->GetWorld(), std::string(name)); return frame ? &(static_cast(frame)->spec) : nullptr; } @@ -487,12 +487,12 @@ mjsFrame* mjs_findFrame(mjSpec* s, const char* name) { // set frame -void mjs_setFrame(mjElement dest, mjsFrame* frame) { +void mjs_setFrame(mjElement* dest, mjsFrame* frame) { if (!frame) { return; } - mjCFrame* frameC = reinterpret_cast(frame->element); - mjCBase* baseC = reinterpret_cast(dest); + mjCFrame* frameC = static_cast(frame->element); + mjCBase* baseC = static_cast(dest); baseC->SetFrame(frameC); } @@ -507,16 +507,16 @@ const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const char* s // get id -int mjs_getId(mjElement element) { - return reinterpret_cast(element)->id; +int mjs_getId(mjElement* element) { + return static_cast(element)->id; } // set default -void mjs_setDefault(mjElement element, mjsDefault* defspec) { - mjCBase* baseC = reinterpret_cast(element); - baseC->def = reinterpret_cast(defspec->element); +void mjs_setDefault(mjElement* element, mjsDefault* defspec) { + mjCBase* baseC = static_cast(element); + baseC->def = static_cast(defspec->element); } @@ -631,7 +631,7 @@ const double* mjs_getDouble(const mjDoubleVec source, int* size) { // set plugin attributes void mjs_setPluginAttributes(mjsPlugin* plugin, void* attributes) { - mjCPlugin* pluginC = reinterpret_cast(plugin->instance); + mjCPlugin* pluginC = static_cast(plugin->instance); std::map>* config_attribs = reinterpret_cast>*>(attributes); pluginC->config_attribs = std::move(*config_attribs); @@ -641,7 +641,7 @@ void mjs_setPluginAttributes(mjsPlugin* plugin, void* attributes) { // Set active plugins. void mjs_setActivePlugins(mjSpec* s, void* activeplugins) { - mjCModel* modelC = reinterpret_cast(s->element); + mjCModel* modelC = static_cast(s->element); std::vector>* active_plugins = reinterpret_cast>*>(activeplugins); modelC->active_plugins = std::move(*active_plugins); @@ -651,7 +651,7 @@ void mjs_setActivePlugins(mjSpec* s, void* activeplugins) { // compute full inertia const char* mjs_setFullInertia(mjsBody* bodyspec, double quat[4], double inertia[3]) { - mjCBody* body = reinterpret_cast(bodyspec->element); + mjCBody* body = static_cast(bodyspec->element); return body->FullInertia(quat, inertia); } diff --git a/src/user/user_api.h b/src/user/user_api.h index a9ac8bde..b448f3e4 100644 --- a/src/user/user_api.h +++ b/src/user/user_api.h @@ -29,7 +29,6 @@ extern "C" { //---------------------------------- handles to internal objects ----------------------------------- -typedef struct _mjElement* mjElement; typedef struct _mjString* mjString; typedef struct _mjStringVec* mjStringVec; typedef struct _mjIntVec* mjIntVec; @@ -77,10 +76,15 @@ typedef enum _mjtInertiaFromGeom { } mjtInertiaFromGeom; -//---------------------------------- attribute structs (mjm) --------------------------------------- +//---------------------------------- attribute structs (mjs) --------------------------------------- + +typedef struct _mjElement { // element type, do not modify + mjtObj elemtype; // element type +} mjElement; + typedef struct _mjSpec { // model specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjStatistic stat; // statistics override (if defined) // compiler settings @@ -144,7 +148,7 @@ typedef struct _mjsOrientation { // alternative orientation specifiers typedef struct _mjsPlugin { // plugin specification - mjElement instance; // internal, do not modify + mjElement* instance; // object type mjString name; // name mjString instance_name; // instance name int plugin_slot; // global registered slot number of the plugin @@ -154,7 +158,7 @@ typedef struct _mjsPlugin { // plugin specification typedef struct _mjsBody { // body specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString childclass; // childclass name @@ -182,7 +186,7 @@ typedef struct _mjsBody { // body specification typedef struct _mjsFrame { // frame specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString childclass; // childclass name double pos[3]; // position @@ -193,7 +197,7 @@ typedef struct _mjsFrame { // frame specification typedef struct _mjsJoint { // joint specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString classname; // class name mjtJoint type; // joint type @@ -233,7 +237,7 @@ typedef struct _mjsJoint { // joint specification typedef struct _mjsGeom { // geom specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString classname; // classname mjtGeom type; // geom type @@ -282,7 +286,7 @@ typedef struct _mjsGeom { // geom specification typedef struct _mjsSite { // site specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString classname; // class name @@ -306,7 +310,7 @@ typedef struct _mjsSite { // site specification typedef struct _mjsCamera { // camera specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString classname; // class name @@ -335,7 +339,7 @@ typedef struct _mjsCamera { // camera specification typedef struct _mjsLight { // light specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString classname; // class name @@ -362,7 +366,7 @@ typedef struct _mjsLight { // light specification typedef struct _mjsFlex { - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString classname; // class name @@ -403,7 +407,7 @@ typedef struct _mjsFlex { typedef struct _mjsMesh { // mesh specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString classname; // class name mjString content_type; // content type of file @@ -424,7 +428,7 @@ typedef struct _mjsMesh { // mesh specification typedef struct _mjsHField { // height field specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString content_type; // content type of file mjString file; // file: (nrow, ncol, [elevation data]) @@ -438,7 +442,7 @@ typedef struct _mjsHField { // height field specification typedef struct _mjsSkin { // skin specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString classname; // class name mjString file; // skin file @@ -465,7 +469,7 @@ typedef struct _mjsSkin { // skin specification typedef struct _mjsTexture { // texture specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString classname; // class name mjtTexture type; // texture type @@ -499,7 +503,7 @@ typedef struct _mjsTexture { // texture specification typedef struct _mjsMaterial { // material specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString classname; // class name mjString texture; // name of texture (empty: none) @@ -515,7 +519,7 @@ typedef struct _mjsMaterial { // material specification typedef struct _mjsPair { - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString classname; // class name mjString geomname1; // name of geom 1 @@ -534,7 +538,7 @@ typedef struct _mjsPair { typedef struct _mjsExclude { - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString bodyname1; // name of geom 1 mjString bodyname2; // name of geom 2 @@ -543,7 +547,7 @@ typedef struct _mjsExclude { typedef struct _mjsEquality { // equality specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString classname; // class name mjtEq type; // constraint type @@ -558,7 +562,7 @@ typedef struct _mjsEquality { // equality specification typedef struct _mjsTendon { // tendon specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString classname; // class name @@ -590,13 +594,13 @@ typedef struct _mjsTendon { // tendon specification typedef struct _mjsWrap { // wrapping object specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString info; // message appended to errors } mjsWrap; typedef struct _mjsActuator { // actuator specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString classname; // class name @@ -640,7 +644,7 @@ typedef struct _mjsActuator { // actuator specification typedef struct _mjsSensor { // sensor specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString classname; // class name @@ -668,7 +672,7 @@ typedef struct _mjsSensor { // sensor specification typedef struct _mjsNumeric { // custom numeric field specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjDoubleVec data; // initialization data int size; // array size, can be bigger than data size @@ -677,7 +681,7 @@ typedef struct _mjsNumeric { // custom numeric field specification typedef struct _mjsText { // custom text specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjString data; // text string mjString info; // message appended to compiler errors @@ -685,7 +689,7 @@ typedef struct _mjsText { // custom text specification typedef struct _mjsTuple { // tuple specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name mjIntVec objtype; // object types mjStringVec objname; // object names @@ -695,7 +699,7 @@ typedef struct _mjsTuple { // tuple specification typedef struct _mjsKey { // keyframe specification - mjElement element; // internal, do not modify + mjElement* element; // object type mjString name; // name double time; // time mjDoubleVec qpos; // qpos @@ -710,7 +714,7 @@ typedef struct _mjsKey { // keyframe specification typedef struct _mjsDefault { // default specification mjString name; // name - mjElement element; // internal, do not modify + mjElement* element; // object type mjsJoint* joint; // joint defaults mjsGeom* geom; // geom defaults mjsSite* site; // site defaults @@ -847,7 +851,7 @@ MJAPI mjsDefault* mjs_addDefault(mjSpec* s, const char* classname, int parentid, MJAPI mjSpec* mjs_getSpec(mjsBody* body); // Get default corresponding to an mjElement. -MJAPI mjsDefault* mjs_getDefault(mjElement element); +MJAPI mjsDefault* mjs_getDefault(mjElement* element); // Find default in model by class name. MJAPI mjsDefault* mjs_findDefault(mjSpec* s, const char* classname); @@ -868,7 +872,7 @@ MJAPI mjsMesh* mjs_findMesh(mjSpec* s, const char* name); MJAPI mjsFrame* mjs_findFrame(mjSpec* s, const char* name); // Get element id. -MJAPI int mjs_getId(mjElement element); +MJAPI int mjs_getId(mjElement* element); // Copy text to string. MJAPI void mjs_setString(mjString dest, const char* text); @@ -910,10 +914,10 @@ MJAPI void mjs_setPluginAttributes(mjsPlugin* plugin, void* attributes); MJAPI void mjs_setActivePlugins(mjSpec* s, void* activeplugins); // Set default. -MJAPI void mjs_setDefault(mjElement element, mjsDefault* def); +MJAPI void mjs_setDefault(mjElement* element, mjsDefault* def); // Set frame. -MJAPI void mjs_setFrame(mjElement dest, mjsFrame* frame); +MJAPI void mjs_setFrame(mjElement* dest, mjsFrame* frame); // Resolve alternative orientations to quat. MJAPI const char* mjs_resolveOrientation(double quat[4], mjtByte degree, const char* sequence, diff --git a/src/user/user_composite.cc b/src/user/user_composite.cc index 4337557d..3a813b11 100644 --- a/src/user/user_composite.cc +++ b/src/user/user_composite.cc @@ -306,7 +306,7 @@ bool mjCComposite::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) // overwrite plugin name if (plugin_instance_name.empty() && plugin.active) { plugin_instance_name = "composite" + prefix; - ((mjCPlugin*)plugin.instance)->name = plugin_instance_name; + (static_cast(plugin.instance))->name = plugin_instance_name; } // dispatch @@ -432,7 +432,7 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjsBody* body, char* error, int mjtNum t = 1; if (dim == 2 && plugin.active) { try { - mjCPlugin* pplugin = (mjCPlugin*)plugin.instance; + mjCPlugin* pplugin = static_cast(plugin.instance); t = std::stod(pplugin->config_attribs["thickness"], nullptr); } catch (const std::invalid_argument& e) { return comperr(error, "Invalid thickness attribute", error_sz); @@ -512,9 +512,9 @@ bool mjCComposite::MakeParticle(mjCModel* model, mjsBody* body, char* error, int // add plugin if (plugin.active) { mjsPlugin* pplugin = &b->plugin; - mjCPlugin* cplugin = (mjCPlugin*)plugin.instance; + mjCPlugin* cplugin = static_cast(plugin.instance); pplugin->active = true; - pplugin->instance = (mjElement)plugin.instance; + pplugin->instance = plugin.instance; mjs_setString(pplugin->instance_name, plugin_instance_name.c_str()); mjs_setString(pplugin->name, mjs_getString(plugin.name)); @@ -868,7 +868,7 @@ mjsBody* mjCComposite::AddCableBody(mjCModel* model, mjsBody* body, int ix, mjtN if (plugin.active) { mjsPlugin* pplugin = &body->plugin; pplugin->active = true; - pplugin->instance = (mjElement)plugin.instance; + pplugin->instance = plugin.instance; mjs_setString(pplugin->name, mjs_getString(plugin.name)); mjs_setString(pplugin->instance_name, plugin_instance_name.c_str()); } diff --git a/src/user/user_flexcomp.cc b/src/user/user_flexcomp.cc index e7cabbed..730f8ab1 100644 --- a/src/user/user_flexcomp.cc +++ b/src/user/user_flexcomp.cc @@ -412,7 +412,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) { // overwrite plugin name if (plugin.active && plugin_instance_name.empty()) { plugin_instance_name = "flexcomp_" + name; - ((mjCPlugin*)plugin.instance)->name = plugin_instance_name; + static_cast(plugin.instance)->name = plugin_instance_name; } // create bodies, construct flex vert and vertbody @@ -430,7 +430,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) { if (plugin.active) { mjsPlugin* pplugin = &body->plugin; pplugin->active = true; - pplugin->instance = (mjElement)plugin.instance; + pplugin->instance = static_cast(plugin.instance); mjs_setString(pplugin->name, mjs_getString(plugin.name)); mjs_setString(pplugin->instance_name, plugin_instance_name.c_str()); } @@ -494,7 +494,7 @@ bool mjCFlexcomp::Make(mjSpec* spec, mjsBody* body, char* error, int error_sz) { if (plugin.active) { mjsPlugin* pplugin = &pb->plugin; pplugin->active = true; - pplugin->instance = (mjElement)plugin.instance; + pplugin->instance = static_cast(plugin.instance); mjs_setString(pplugin->name, mjs_getString(plugin.name)); mjs_setString(pplugin->instance_name, plugin_instance_name.c_str()); } diff --git a/src/user/user_mesh.cc b/src/user/user_mesh.cc index 1bd6f5b4..cfed0213 100644 --- a/src/user/user_mesh.cc +++ b/src/user/user_mesh.cc @@ -131,6 +131,7 @@ static void ReadFromBuffer(T* dst, const char* src) { mjCMesh::mjCMesh(mjCModel* _model, mjCDef* _def) { mjs_defaultMesh(spec); + elemtype = mjOBJ_MESH; // clear internal variables mjuu_setvec(pos_surface_, 0, 0, 0); @@ -253,7 +254,7 @@ mjCMesh& mjCMesh::operator=(const mjCMesh& other) { this->graph_ = NULL; } if (other.plugin.instance) { - mjCPlugin* new_plugin = new mjCPlugin(*reinterpret_cast(other.plugin.instance)); + mjCPlugin* new_plugin = new mjCPlugin(*static_cast(other.plugin.instance)); plugin = new_plugin->spec; model->plugins.push_back(new_plugin); } @@ -265,7 +266,7 @@ mjCMesh& mjCMesh::operator=(const mjCMesh& other) { void mjCMesh::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.classname = (mjString)&classname; spec.file = (mjString)&spec_file_; @@ -358,8 +359,9 @@ void mjCMesh::LoadSDF() { name.c_str(), id); } - mjCPlugin* plugin_instance = (mjCPlugin*)plugin.instance; + mjCPlugin* plugin_instance = static_cast(plugin.instance); model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance); + plugin.instance = plugin_instance; const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot); if (!(pplugin->capabilityflags & mjPLUGIN_SDF)) { throw mjCError(this, "plugin '%s' does not support signed distance fields", pplugin->name); @@ -2056,6 +2058,7 @@ void mjCMesh::MakeCenter(void) { // constructor mjCSkin::mjCSkin(mjCModel* _model) { mjs_defaultSkin(spec); + elemtype = mjOBJ_SKIN; // set model pointer model = _model; @@ -2103,7 +2106,7 @@ mjCSkin& mjCSkin::operator=(const mjCSkin& other) { void mjCSkin::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.classname = (mjString)&classname; spec.file = (mjString)&spec_file_; @@ -2480,6 +2483,7 @@ constexpr int eledge[3][6][2] = {{{ 0, 1}, {-1, -1}, {-1, -1}, // constructor mjCFlex::mjCFlex(mjCModel* _model) { mjs_defaultFlex(spec); + elemtype = mjOBJ_FLEX; // set model model = _model; @@ -2514,7 +2518,7 @@ mjCFlex& mjCFlex::operator=(const mjCFlex& other) { void mjCFlex::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.classname = (mjString)&classname; spec.material = (mjString)&spec_material_; @@ -2756,7 +2760,8 @@ void mjCFlex::Compile(const mjVFS* vfs) { for (int i=0; i<(int)vertbodyid.size(); i++) { if (model->bodies[vertbodyid[i]]->plugin.instance) { - mjCPlugin* plugin_instance = (mjCPlugin*)model->bodies[vertbodyid[i]]->plugin.instance; + mjCPlugin* plugin_instance = + static_cast(model->bodies[vertbodyid[i]]->plugin.instance); plugin_instance->config_attribs["face"] = userface; plugin_instance->config_attribs["edge"] = useredge; } diff --git a/src/user/user_model.cc b/src/user/user_model.cc index c160a8a0..284f0260 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -84,6 +84,7 @@ static void copyvec(T1* dest, T2* src, int n) { // constructor mjCModel::mjCModel() { mjs_defaultSpec(spec); + elemtype = mjOBJ_UNKNOWN; spec_comment_.clear(); spec_modelfiledir_.clear(); spec_meshdir_.clear(); @@ -319,7 +320,7 @@ void mjCModel::CreateObjectLists() { void mjCModel::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.comment = (mjString)&spec_comment_; spec.modelfiledir = (mjString)&spec_modelfiledir_; spec.modelname = (mjString)&spec_modelname_; @@ -3226,7 +3227,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) { std::vector> plugin_to_actuators(nplugin); for (int i = 0; i < nu; ++i) { if (actuators[i]->plugin.active) { - int actuator_plugin = ((mjCPlugin*)actuators[i]->plugin.instance)->id; + int actuator_plugin = static_cast(actuators[i]->plugin.instance)->id; m->actuator_plugin[i] = actuator_plugin; plugin_to_actuators[actuator_plugin].push_back(i); } else { @@ -3236,7 +3237,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) { for (int i = 0; i < nbody; ++i) { if (bodies[i]->plugin.active) { - m->body_plugin[i] = ((mjCPlugin*)bodies[i]->plugin.instance)->id; + m->body_plugin[i] = static_cast(bodies[i]->plugin.instance)->id; } else { m->body_plugin[i] = -1; } @@ -3244,7 +3245,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) { for (int i = 0; i < ngeom; ++i) { if (geoms[i]->plugin.active) { - m->geom_plugin[i] = ((mjCPlugin*)geoms[i]->plugin.instance)->id; + m->geom_plugin[i] = static_cast(geoms[i]->plugin.instance)->id; } else { m->geom_plugin[i] = -1; } @@ -3253,7 +3254,7 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) { std::vector> plugin_to_sensors(nplugin); for (int i = 0; i < nsensor; ++i) { if (sensors[i]->type == mjSENS_PLUGIN) { - int sensor_plugin = ((mjCPlugin*)sensors[i]->plugin.instance)->id; + int sensor_plugin = static_cast(sensors[i]->plugin.instance)->id; m->sensor_plugin[i] = sensor_plugin; plugin_to_sensors[sensor_plugin].push_back(i); } else { diff --git a/src/user/user_model.h b/src/user/user_model.h index 167d3840..2256ea3b 100644 --- a/src/user/user_model.h +++ b/src/user/user_model.h @@ -33,7 +33,7 @@ typedef std::map > mjKeyMap; typedef std::array mjListKeyMap; -class mjCModel_ { +class mjCModel_ : public mjElement { public: // attach namespaces std::string prefix; diff --git a/src/user/user_objects.cc b/src/user/user_objects.cc index 6b5d41ee..e6383cc0 100644 --- a/src/user/user_objects.cc +++ b/src/user/user_objects.cc @@ -516,7 +516,7 @@ void mjCDef::PointToLocal() { equality.PointToLocal(); tendon.PointToLocal(); actuator.PointToLocal(); - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.joint = &joint.spec; spec.geom = &geom.spec; @@ -632,6 +632,7 @@ mjCBody::mjCBody(mjCModel* _model) { model = _model; mjs_defaultBody(spec); + elemtype = mjOBJ_BODY; parentid = -1; weldid = -1; dofnum = 0; @@ -745,7 +746,7 @@ mjCBody& mjCBody::operator+=(mjCBody& other) { void mjCBody::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.childclass = (mjString)&classname; spec.userdata = (mjDoubleVec)&spec_userdata_; @@ -1337,9 +1338,10 @@ void mjCBody::Compile(void) { name.c_str(), id); } - mjCPlugin** plugin_instance = (mjCPlugin**)&plugin.instance; - model->ResolvePlugin(this, plugin_name, plugin_instance_name, plugin_instance); - const mjpPlugin* pplugin = mjp_getPluginAtSlot((*plugin_instance)->spec.plugin_slot); + mjCPlugin* plugin_instance = static_cast(plugin.instance); + model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance); + plugin.instance = plugin_instance; + const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot); if (!(pplugin->capabilityflags & mjPLUGIN_PASSIVE)) { throw mjCError(this, "plugin '%s' does not support passive forces", pplugin->name); } @@ -1365,6 +1367,7 @@ void mjCBody::Compile(void) { // initialize frame mjCFrame::mjCFrame(mjCModel* _model, mjCFrame* _frame) { mjs_defaultFrame(spec); + elemtype = mjOBJ_FRAME; compiled = false; model = _model; body = NULL; @@ -1417,7 +1420,7 @@ void mjCFrame::SetParent(mjCBody* _body) { void mjCFrame::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.childclass = (mjString)&classname; spec.info = (mjString)&info; @@ -1461,6 +1464,7 @@ void mjCFrame::Compile() { // initialize default joint mjCJoint::mjCJoint(mjCModel* _model, mjCDef* _def) { mjs_defaultJoint(spec); + elemtype = mjOBJ_JOINT; // clear internal variables spec_userdata_.clear(); @@ -1508,7 +1512,7 @@ bool mjCJoint::is_actfrclimited() const { return islimited(actfrclimited, actfrc void mjCJoint::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.classname = (mjString)&classname; spec.userdata = (mjDoubleVec)&spec_userdata_; @@ -1658,6 +1662,7 @@ int mjCJoint::Compile(void) { // initialize default geom mjCGeom::mjCGeom(mjCModel* _model, mjCDef* _def) { mjs_defaultGeom(spec); + elemtype = mjOBJ_GEOM; mass_ = 0; body = 0; @@ -1715,7 +1720,7 @@ mjCGeom& mjCGeom::operator=(const mjCGeom& other) { // to be called after any default copy constructor void mjCGeom::PointToLocal(void) { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.info = (mjString)&info; spec.classname = (mjString)&classname; @@ -2263,9 +2268,10 @@ void mjCGeom::Compile(void) { name.c_str(), id); } - mjCPlugin** plugin_instance = (mjCPlugin**)&plugin.instance; - model->ResolvePlugin(this, plugin_name, plugin_instance_name, plugin_instance); - const mjpPlugin* pplugin = mjp_getPluginAtSlot((*plugin_instance)->spec.plugin_slot); + mjCPlugin* plugin_instance = static_cast(plugin.instance); + model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance); + plugin.instance = plugin_instance; + const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot); if (!(pplugin->capabilityflags & mjPLUGIN_SDF)) { throw mjCError(this, "plugin '%s' does not support sign distance fields", pplugin->name); } @@ -2284,6 +2290,7 @@ void mjCGeom::Compile(void) { // initialize default site mjCSite::mjCSite(mjCModel* _model, mjCDef* _def) { mjs_defaultSite(spec); + elemtype = mjOBJ_SITE; // clear internal variables body = 0; @@ -2328,7 +2335,7 @@ mjCSite& mjCSite::operator=(const mjCSite& other) { void mjCSite::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.info = (mjString)&info; spec.classname = (mjString)&classname; @@ -2440,6 +2447,7 @@ void mjCSite::Compile(void) { // initialize defaults mjCCamera::mjCCamera(mjCModel* _model, mjCDef* _def) { mjs_defaultCamera(spec); + elemtype = mjOBJ_CAMERA; // clear private variables body = 0; @@ -2483,7 +2491,7 @@ mjCCamera& mjCCamera::operator=(const mjCCamera& other) { void mjCCamera::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.classname = (mjString)&classname; spec.userdata = (mjDoubleVec)&spec_userdata_; @@ -2590,6 +2598,7 @@ void mjCCamera::Compile(void) { // initialize defaults mjCLight::mjCLight(mjCModel* _model, mjCDef* _def) { mjs_defaultLight(spec); + elemtype = mjOBJ_LIGHT; // clear private variables body = 0; @@ -2630,7 +2639,7 @@ mjCLight& mjCLight::operator=(const mjCLight& other) { void mjCLight::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.classname = (mjString)&classname; spec.targetbody = (mjString)&spec_targetbody_; @@ -2686,6 +2695,7 @@ void mjCLight::Compile(void) { // constructor mjCHField::mjCHField(mjCModel* _model) { mjs_defaultHField(spec); + elemtype = mjOBJ_HFIELD; // set model pointer model = _model; @@ -2723,7 +2733,7 @@ mjCHField& mjCHField::operator=(const mjCHField& other) { void mjCHField::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.file = (mjString)&spec_file_; spec.content_type = (mjString)&spec_content_type_; @@ -2938,6 +2948,7 @@ void mjCHField::Compile(const mjVFS* vfs) { // initialize defaults mjCTexture::mjCTexture(mjCModel* _model) { mjs_defaultTexture(spec); + elemtype = mjOBJ_TEXTURE; // set model pointer model = _model; @@ -2979,7 +2990,7 @@ mjCTexture& mjCTexture::operator=(const mjCTexture& other) { void mjCTexture::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.classname = (mjString)&classname; spec.file = (mjString)&spec_file_; @@ -3680,6 +3691,7 @@ void mjCTexture::Compile(const mjVFS* vfs) { // initialize defaults mjCMaterial::mjCMaterial(mjCModel* _model, mjCDef* _def) { mjs_defaultMaterial(spec); + elemtype = mjOBJ_MATERIAL; // clear internal spec_texture_.clear(); @@ -3722,7 +3734,7 @@ mjCMaterial& mjCMaterial::operator=(const mjCMaterial& other) { void mjCMaterial::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.classname = (mjString)&classname; spec.texture = (mjString)&spec_texture_; @@ -3751,6 +3763,7 @@ void mjCMaterial::Compile(void) { // constructor mjCPair::mjCPair(mjCModel* _model, mjCDef* _def) { mjs_defaultPair(spec); + elemtype = mjOBJ_PAIR; // set defaults spec_geomname1_.clear(); @@ -3800,7 +3813,7 @@ mjCPair& mjCPair::operator=(const mjCPair& other) { void mjCPair::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.classname = (mjString)&classname; spec.geomname1 = (mjString)&spec_geomname1_; @@ -4010,7 +4023,7 @@ mjCBodyPair& mjCBodyPair::operator=(const mjCBodyPair& other) { void mjCBodyPair::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.bodyname1 = (mjString)&spec_bodyname1_; spec.bodyname2 = (mjString)&spec_bodyname2_; @@ -4086,6 +4099,7 @@ void mjCBodyPair::Compile(void) { // initialize default constraint mjCEquality::mjCEquality(mjCModel* _model, mjCDef* _def) { mjs_defaultEquality(spec); + elemtype = mjOBJ_EQUALITY; // clear internal variables spec_name1_.clear(); @@ -4129,7 +4143,7 @@ mjCEquality& mjCEquality::operator=(const mjCEquality& other) { void mjCEquality::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.classname = (mjString)&classname; spec.name1 = (mjString)&spec_name1_; @@ -4248,6 +4262,7 @@ void mjCEquality::Compile(void) { // constructor mjCTendon::mjCTendon(mjCModel* _model, mjCDef* _def) { mjs_defaultTendon(spec); + elemtype = mjOBJ_TENDON; // clear internal variables spec_material_.clear(); @@ -4299,7 +4314,7 @@ bool mjCTendon::is_limited() const { return islimited(limited, range); } void mjCTendon::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.classname = (mjString)&classname; spec.material = (mjString)&spec_material_; @@ -4576,6 +4591,8 @@ void mjCTendon::Compile(void) { // constructor mjCWrap::mjCWrap(mjCModel* _model, mjCTendon* _tendon) { + elemtype = mjOBJ_UNKNOWN; + // set model and tendon pointer model = _model; tendon = _tendon; @@ -4613,7 +4630,7 @@ mjCWrap& mjCWrap::operator=(const mjCWrap& other) { void mjCWrap::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.info = (mjString)&info; } @@ -4705,6 +4722,7 @@ void mjCWrap::ResolveReferences(const mjCModel* m) { // initialize defaults mjCActuator::mjCActuator(mjCModel* _model, mjCDef* _def) { mjs_defaultActuator(spec); + elemtype = mjOBJ_ACTUATOR; // clear private variables ptarget = nullptr; @@ -4758,7 +4776,7 @@ bool mjCActuator::is_actlimited() const { return islimited(actlimited, actrange) void mjCActuator::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.classname = (mjString)&classname; spec.userdata = (mjDoubleVec)&spec_userdata_; @@ -5032,9 +5050,10 @@ void mjCActuator::Compile(void) { name.c_str(), id); } - mjCPlugin** plugin_instance = (mjCPlugin**)&plugin.instance; - model->ResolvePlugin(this, plugin_name, plugin_instance_name, plugin_instance); - const mjpPlugin* pplugin = mjp_getPluginAtSlot((*plugin_instance)->spec.plugin_slot); + mjCPlugin* plugin_instance = static_cast(plugin.instance); + model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance); + plugin.instance = plugin_instance; + const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot); if (!(pplugin->capabilityflags & mjPLUGIN_ACTUATOR)) { throw mjCError(this, "plugin '%s' does not support actuators", pplugin->name); } @@ -5048,6 +5067,7 @@ void mjCActuator::Compile(void) { // initialize defaults mjCSensor::mjCSensor(mjCModel* _model) { mjs_defaultSensor(spec); + elemtype = mjOBJ_SENSOR; // set model model = _model; @@ -5090,7 +5110,7 @@ mjCSensor& mjCSensor::operator=(const mjCSensor& other) { void mjCSensor::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.classname = (mjString)&classname; spec.userdata = (mjDoubleVec)&spec_userdata_; @@ -5504,9 +5524,10 @@ void mjCSensor::Compile(void) { // resolve plugin instance, or create one if using the "plugin" attribute shortcut { - mjCPlugin** plugin_instance = (mjCPlugin**)&plugin.instance; - model->ResolvePlugin(this, plugin_name, plugin_instance_name, plugin_instance); - const mjpPlugin* pplugin = mjp_getPluginAtSlot((*plugin_instance)->spec.plugin_slot); + mjCPlugin* plugin_instance = static_cast(plugin.instance); + model->ResolvePlugin(this, plugin_name, plugin_instance_name, &plugin_instance); + plugin.instance = plugin_instance; + const mjpPlugin* pplugin = mjp_getPluginAtSlot(plugin_instance->spec.plugin_slot); if (!(pplugin->capabilityflags & mjPLUGIN_SENSOR)) { throw mjCError(this, "plugin '%s' does not support sensors", pplugin->name); } @@ -5534,6 +5555,7 @@ void mjCSensor::Compile(void) { // constructor mjCNumeric::mjCNumeric(mjCModel* _model) { mjs_defaultNumeric(spec); + elemtype = mjOBJ_NUMERIC; // set model pointer model = _model; @@ -5569,7 +5591,7 @@ mjCNumeric& mjCNumeric::operator=(const mjCNumeric& other) { void mjCNumeric::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.data = (mjDoubleVec)&spec_data_; spec.info = (mjString)&info; @@ -5622,6 +5644,7 @@ void mjCNumeric::Compile(void) { // constructor mjCText::mjCText(mjCModel* _model) { mjs_defaultText(spec); + elemtype = mjOBJ_TEXT; // set model pointer model = _model; @@ -5657,7 +5680,7 @@ mjCText& mjCText::operator=(const mjCText& other) { void mjCText::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.data = (mjString)&spec_data_; spec.info = (mjString)&info; @@ -5698,6 +5721,7 @@ void mjCText::Compile(void) { // constructor mjCTuple::mjCTuple(mjCModel* _model) { mjs_defaultTuple(spec); + elemtype = mjOBJ_TUPLE; // set model pointer model = _model; @@ -5736,7 +5760,7 @@ mjCTuple& mjCTuple::operator=(const mjCTuple& other) { void mjCTuple::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.objtype = (mjIntVec)&spec_objtype_; spec.objname = (mjStringVec)&spec_objname_; @@ -5830,6 +5854,7 @@ void mjCTuple::Compile(void) { // constructor mjCKey::mjCKey(mjCModel* _model) { mjs_defaultKey(spec); + elemtype = mjOBJ_KEY; // set model pointer model = _model; @@ -5870,7 +5895,7 @@ mjCKey& mjCKey::operator=(const mjCKey& other) { void mjCKey::PointToLocal() { - spec.element = (mjElement)this; + spec.element = static_cast(this); spec.name = (mjString)&name; spec.qpos = (mjDoubleVec)&spec_qpos_; spec.qvel = (mjDoubleVec)&spec_qvel_; @@ -6013,6 +6038,7 @@ mjCPlugin::mjCPlugin(mjCModel* _model) { // public interface mjs_defaultPlugin(spec); + elemtype = mjOBJ_PLUGIN; spec.name = (mjString)&name; spec.instance_name = (mjString)&instance_name; spec.info = (mjString)&info; diff --git a/src/user/user_objects.h b/src/user/user_objects.h index 1e24ab34..df1ef8bb 100644 --- a/src/user/user_objects.h +++ b/src/user/user_objects.h @@ -167,7 +167,7 @@ class mjCBoundingVolumeHierarchy : public mjCBoundingVolumeHierarchy_ { //------------------------- class mjCBase ---------------------------------------------------------- // Generic functionality for all derived classes -class mjCBase_ { +class mjCBase_ : public mjElement { public: int id; // object id std::string name; // object name @@ -1606,7 +1606,7 @@ class mjCKey : public mjCKey_, private mjsKey { //------------------------- class mjCDef ----------------------------------------------------------- // Describes one set of defaults -class mjCDef { +class mjCDef : public mjElement { friend class mjXWriter; public: diff --git a/src/xml/xml_native_writer.cc b/src/xml/xml_native_writer.cc index 642a96d4..9a20b95a 100644 --- a/src/xml/xml_native_writer.cc +++ b/src/xml/xml_native_writer.cc @@ -739,8 +739,8 @@ void mjXWriter::OnePlugin(XMLElement* elem, mjsPlugin* plugin) { } else { WriteAttrTxt(elem, "plugin", plugin_name); const mjpPlugin* pplugin = mjp_getPluginAtSlot( - ((mjCPlugin*)plugin->instance)->spec.plugin_slot); - const char* c = &((mjCPlugin*)plugin->instance)->flattened_attributes[0]; + static_cast(plugin->instance)->spec.plugin_slot); + const char* c = &(static_cast(plugin->instance)->flattened_attributes[0]); for (int i = 0; i < pplugin->nattribute; ++i) { std::string value(c); if (!value.empty()) { From 96f923282cb7d36a309bfdbb98d269f0f7702e0b Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Thu, 28 Mar 2024 05:25:28 -0700 Subject: [PATCH 43/51] Add SetNuser function. PiperOrigin-RevId: 619892712 Change-Id: Id528620d6af19976d965f34a3be95a48a1f9c0b2 --- src/user/user_model.cc | 192 +++++++++++++++++++++-------------------- src/user/user_model.h | 1 + 2 files changed, 99 insertions(+), 94 deletions(-) diff --git a/src/user/user_model.cc b/src/user/user_model.cc index 284f0260..0217359c 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -932,103 +932,154 @@ void mjCModel::DeleteAll(std::vector& elements) { elements.clear(); } +// set nuser fields +void mjCModel::SetNuser(){ + if (nuser_body == -1) { + nuser_body = 0; + for (int i=0; ispec_userdata_.size()); + } + } + if (nuser_jnt == -1) { + nuser_jnt = 0; + for (int i=0; ispec_userdata_.size()); + } + } + if (nuser_geom == -1) { + nuser_geom = 0; + for (int i=0; ispec_userdata_.size()); + } + } + if (nuser_site == -1) { + nuser_site = 0; + for (int i=0; ispec_userdata_.size()); + } + } + if (nuser_cam == -1) { + nuser_cam = 0; + for (int i=0; ispec_userdata_.size()); + } + } + if (nuser_tendon == -1) { + nuser_tendon = 0; + for (int i=0; ispec_userdata_.size()); + } + } + if (nuser_actuator == -1) { + nuser_actuator = 0; + for (int i=0; ispec_userdata_.size()); + } + } + if (nuser_sensor == -1) { + nuser_sensor = 0; + for (int i=0; ispec_userdata_.size()); + } + } +} // index assets void mjCModel::IndexAssets(bool discard) { // assets referenced in geoms for (int i=0; iget_material().empty()) { - mjCBase* m = FindObject(mjOBJ_MATERIAL, pgeom->get_material()); - if (m) { - pgeom->matid = m->id; + if (!geom->get_material().empty()) { + mjCBase* material = FindObject(mjOBJ_MATERIAL, geom->get_material()); + if (material) { + geom->matid = material->id; } else { - throw mjCError(pgeom, "material '%s' not found in geom %d", pgeom->get_material().c_str(), i); + throw mjCError(geom, "material '%s' not found in geom %d", geom->get_material().c_str(), i); } } // find mesh by name - if (!pgeom->get_meshname().empty()) { - mjCBase* pmesh = FindObject(mjOBJ_MESH, pgeom->get_meshname()); - if (pmesh) { - if (!pgeom->visual_) { - ((mjCMesh*)pmesh)->SetNotVisual(); // reset to true by mesh->Compile() + if (!geom->get_meshname().empty()) { + mjCBase* mesh = FindObject(mjOBJ_MESH, geom->get_meshname()); + if (mesh) { + if (!geom->visual_) { + ((mjCMesh*)mesh)->SetNotVisual(); // reset to true by mesh->Compile() } - pgeom->mesh = (discard && pgeom->visual_) ? nullptr : (mjCMesh*)pmesh; + geom->mesh = (discard && geom->visual_) ? nullptr : (mjCMesh*)mesh; } else { - throw mjCError(pgeom, "mesh '%s' not found in geom %d", pgeom->get_meshname().c_str(), i); + throw mjCError(geom, "mesh '%s' not found in geom %d", geom->get_meshname().c_str(), i); } } // find hfield by name - if (!pgeom->get_hfieldname().empty()) { - mjCBase* m = FindObject(mjOBJ_HFIELD, pgeom->get_hfieldname()); - if (m) { - pgeom->hfield = (mjCHField*)m; + if (!geom->get_hfieldname().empty()) { + mjCBase* hfield = FindObject(mjOBJ_HFIELD, geom->get_hfieldname()); + if (hfield) { + geom->hfield = (mjCHField*)hfield; } else { - throw mjCError(pgeom, "hfield '%s' not found in geom %d", pgeom->get_hfieldname().c_str(), i); + throw mjCError(geom, "hfield '%s' not found in geom %d", geom->get_hfieldname().c_str(), i); } } } // assets referenced in skins for (int i=0; imaterial_.empty()) { - mjCBase* m = FindObject(mjOBJ_MATERIAL, pskin->material_); - if (m) { - pskin->matid = m->id; + if (!skin->material_.empty()) { + mjCBase* material = FindObject(mjOBJ_MATERIAL, skin->material_); + if (material) { + skin->matid = material->id; } else { - throw mjCError(pskin, "material '%s' not found in skin %d", pskin->material_.c_str(), i); + throw mjCError(skin, "material '%s' not found in skin %d", skin->material_.c_str(), i); } } } // materials referenced in sites for (int i=0; imaterial_.empty()) { - mjCBase* m = FindObject(mjOBJ_MATERIAL, psite->get_material()); - if (m) { - psite->matid = m->id; + if (!site->material_.empty()) { + mjCBase* material = FindObject(mjOBJ_MATERIAL, site->get_material()); + if (material) { + site->matid = material->id; } else { - throw mjCError(psite, "material '%s' not found in site %d", psite->material_.c_str(), i); + throw mjCError(site, "material '%s' not found in site %d", site->material_.c_str(), i); } } } // materials referenced in tendons for (int i=0; imaterial_.empty()) { - mjCBase* m = FindObject(mjOBJ_MATERIAL, pten->material_); - if (m) { - pten->matid = m->id; + if (!tendon->material_.empty()) { + mjCBase* material = FindObject(mjOBJ_MATERIAL, tendon->material_); + if (material) { + tendon->matid = material->id; } else { - throw mjCError(pten, "material '%s' not found in tendon %d", pten->material_.c_str(), i); + throw mjCError(tendon, "material '%s' not found in tendon %d", tendon->material_.c_str(), i); } } } // textures referenced in materials for (int i=0; itexture_.empty()) { - mjCBase* m = FindObject(mjOBJ_TEXTURE, pmat->texture_); - if (m) { - pmat->texid = m->id; + if (!material->texture_.empty()) { + mjCBase* texture = FindObject(mjOBJ_TEXTURE, material->texture_); + if (texture) { + material->texid = texture->id; } else { - throw mjCError(pmat, "texture '%s' not found in material %d", pmat->texture_.c_str(), i); + throw mjCError(material, "texture '%s' not found in material %d", material->texture_.c_str(), i); } } } @@ -3039,8 +3090,8 @@ void mjCModel::TryCompile(mjModel*& m, mjData*& d, const mjVFS* vfs) { DeleteAll(textures); } - // convert names into indices - IndexAssets(false); + // map names to asset references + IndexAssets(/*discard=*/false); // mark meshes that need convex hull for (int i=0; iCompile(vfs); } - // automatically set nuser fields - if (nuser_body == -1) { - nuser_body = 0; - for (int i=0; ispec_userdata_.size()); - } - } - if (nuser_jnt == -1) { - nuser_jnt = 0; - for (int i=0; ispec_userdata_.size()); - } - } - if (nuser_geom == -1) { - nuser_geom = 0; - for (int i=0; ispec_userdata_.size()); - } - } - if (nuser_site == -1) { - nuser_site = 0; - for (int i=0; ispec_userdata_.size()); - } - } - if (nuser_cam == -1) { - nuser_cam = 0; - for (int i=0; ispec_userdata_.size()); - } - } - if (nuser_tendon == -1) { - nuser_tendon = 0; - for (int i=0; ispec_userdata_.size()); - } - } - if (nuser_actuator == -1) { - nuser_actuator = 0; - for (int i=0; ispec_userdata_.size()); - } - } - if (nuser_sensor == -1) { - nuser_sensor = 0; - for (int i=0; ispec_userdata_.size()); - } - } - // compile objects in kinematic tree for (int i=0; iCompile(); // also compiles joints, geoms, sites, cameras, lights diff --git a/src/user/user_model.h b/src/user/user_model.h index 2256ea3b..18d1607b 100644 --- a/src/user/user_model.h +++ b/src/user/user_model.h @@ -256,6 +256,7 @@ class mjCModel : public mjCModel_, private mjSpec { // compile phases void MakeLists(mjCBody* body); // make lists of bodies, geoms, joints, sites + void SetNuser(); // set nuser fields void IndexAssets(bool discard); // convert asset names into indices void CheckEmptyNames(); // check empty names void SetSizes(); // compute sizes From a8db22f0d077aee86f771808fd24ea60a148c93f Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Thu, 28 Mar 2024 08:56:26 -0700 Subject: [PATCH 44/51] Add local vector clamping function in engine_forward.c PiperOrigin-RevId: 619948315 Change-Id: Ie4b92f5c8facaa2c169f01982940e84a0248b9c9 --- src/engine/engine_forward.c | 49 ++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/src/engine/engine_forward.c b/src/engine/engine_forward.c index 5f51c5a9..bcaa55ff 100644 --- a/src/engine/engine_forward.c +++ b/src/engine/engine_forward.c @@ -243,6 +243,19 @@ static mjtNum nextActivation(const mjModel* m, const mjData* d, +// clamp vector to range +static void mju_clamp(mjtNum* vec, const mjtNum* range, const mjtByte* limited, int n, + const int* index) { + for (int i=0; i < n; i++) { + int j = index ? index[i] : i; + if (limited[i]) { + vec[j] = mju_clip(vec[j], range[2*i], range[2*i + 1]); + } + } +} + + + // (qpos, qvel, ctrl, act) => (qfrc_actuator, actuator_force, act_dot) void mj_fwdActuation(const mjModel* m, mjData* d) { TM_START; @@ -262,18 +275,9 @@ void mj_fwdActuation(const mjModel* m, mjData* d) { // local, clamped copy of ctrl mj_markStack(d); mjtNum *ctrl = mj_stackAllocNum(d, nu); - if (mjDISABLED(mjDSBL_CLAMPCTRL)) { - mju_copy(ctrl, d->ctrl, nu); - } else { - for (int i=0; i < nu; i++) { - // clamp ctrl - if (m->actuator_ctrllimited[i]) { - mjtNum *ctrlrange = m->actuator_ctrlrange + 2*i; - ctrl[i] = mju_clip(d->ctrl[i], ctrlrange[0], ctrlrange[1]); - } else { - ctrl[i] = d->ctrl[i]; - } - } + mju_copy(ctrl, d->ctrl, nu); + if (!mjDISABLED(mjDSBL_CLAMPCTRL)) { + mju_clamp(ctrl, m->actuator_ctrlrange, m->actuator_ctrllimited, nu, NULL); } // check controls, set all to 0 if any are bad @@ -459,25 +463,13 @@ void mj_fwdActuation(const mjModel* m, mjData* d) { } // clamp actuator_force - for (int i=0; i < nu; i++) { - if (m->actuator_forcelimited[i]) { - mjtNum *forcerange = m->actuator_forcerange + 2*i; - force[i] = mju_clip(force[i], forcerange[0], forcerange[1]); - } - } + mju_clamp(force, m->actuator_forcerange, m->actuator_forcelimited, nu, NULL); // qfrc_actuator = moment' * force mju_mulMatTVec(d->qfrc_actuator, moment, force, nu, nv); // clamp qfrc_actuator - int njnt = m->njnt; - for (int i=0; i < njnt; i++) { - if (m->jnt_actfrclimited[i]) { - mjtNum *forcerange = m->jnt_actfrcrange + 2*i; - mjtNum *qfrc = d->qfrc_actuator + m->jnt_dofadr[i]; - qfrc[0] = mju_clip(qfrc[0], forcerange[0], forcerange[1]); - } - } + mju_clamp(d->qfrc_actuator, m->jnt_actfrcrange, m->jnt_actfrclimited, m->njnt, m->jnt_dofadr); mj_freeStack(d); TM_END(mjTIMER_ACTUATION); @@ -706,9 +698,10 @@ void mj_fwdConstraint(const mjModel* m, mjData* d) { // advance state and time given activation derivatives, acceleration, and optional velocity static void mj_advance(const mjModel* m, mjData* d, const mjtNum* act_dot, const mjtNum* qacc, const mjtNum* qvel) { - // advance activations and clamp + // advance activations if (m->na && !mjDISABLED(mjDSBL_ACTUATION)) { - for (int i=0; i < m->nu; i++) { + int nu = m->nu; + for (int i=0; i < nu; i++) { int actadr = m->actuator_actadr[i]; int actadr_end = actadr + m->actuator_actnum[i]; for (int j=actadr; j < actadr_end; j++) { From d258d5e152d209eb0200412ae17d6e441e488274 Mon Sep 17 00:00:00 2001 From: Baruch Tabanpour Date: Thu, 28 Mar 2024 11:32:44 -0700 Subject: [PATCH 45/51] Check all edge pairs in convex-convex. PiperOrigin-RevId: 620004680 Change-Id: I5d75c0fd21ed3d3e420eed762cfc5a7e04896032 --- doc/mjx.rst | 5 +- mjx/mujoco/mjx/_src/collision_base.py | 6 +- mjx/mujoco/mjx/_src/collision_convex.py | 168 ++++++++---------- mjx/mujoco/mjx/_src/collision_driver.py | 14 +- mjx/mujoco/mjx/_src/collision_driver_test.py | 44 ++++- mjx/mujoco/mjx/_src/mesh.py | 29 ++- mjx/mujoco/mjx/_src/mesh_test.py | 17 +- mjx/mujoco/mjx/_src/types.py | 4 +- .../mjx/test_data/shadow_hand/right_hand.xml | 10 +- 9 files changed, 149 insertions(+), 148 deletions(-) diff --git a/doc/mjx.rst b/doc/mjx.rst index 330336ee..b53708f6 100644 --- a/doc/mjx.rst +++ b/doc/mjx.rst @@ -299,8 +299,9 @@ Collisions between large meshes SAT works well for smaller meshes but suffers in both runtime and memory for larger meshes. For - collisions with convex meshes, the convex decompositon of the mesh should have - roughly **200 vertices or less** for reasonable performance. + collisions with convex meshes and primitives, the convex decompositon of the mesh should have + roughly **200 vertices or less** for reasonable performance. For convex-convex collisions, + the convex mesh should have roughly **fewer than 32 vertices**. With careful tuning, MJX can simulate scenes with mesh collisions -- see the MJX `shadow hand `__ diff --git a/mjx/mujoco/mjx/_src/collision_base.py b/mjx/mujoco/mjx/_src/collision_base.py index cb6293da..423200ac 100644 --- a/mjx/mujoco/mjx/_src/collision_base.py +++ b/mjx/mujoco/mjx/_src/collision_base.py @@ -50,10 +50,10 @@ class GeomInfo(PyTreeNode): size: jax.Array face: Optional[jax.Array] = None vert: Optional[jax.Array] = None - edge: Optional[jax.Array] = None + edge_dir: Optional[jax.Array] = None facenorm: Optional[jax.Array] = None - face_edge: Optional[jax.Array] = None - face_edge_normal: Optional[jax.Array] = None + edge: Optional[jax.Array] = None + edge_face_normal: Optional[jax.Array] = None class SolverParams(PyTreeNode): diff --git a/mjx/mujoco/mjx/_src/collision_convex.py b/mjx/mujoco/mjx/_src/collision_convex.py index 26eb5e8a..1e501097 100644 --- a/mjx/mujoco/mjx/_src/collision_convex.py +++ b/mjx/mujoco/mjx/_src/collision_convex.py @@ -336,8 +336,8 @@ def capsule_convex(cap: GeomInfo, convex: GeomInfo) -> Contact: cap_closest_pt, ) - edge = jp.take(convex.vert, convex.face_edge, axis=0).reshape(-1, 2, 3) - face_edge_normal = convex.face_edge_normal.reshape((-1, 2, 3)) # pytype: disable=attribute-error + edge = jp.take(convex.vert, convex.edge, axis=0) + edge_face_normal = convex.edge_face_normal # pytype: disable=attribute-error res = jax.vmap(get_edge_axis)(edge.reshape(-1, 2, 3)) e_idx = jp.abs(res[0]).argmin() @@ -349,8 +349,8 @@ def capsule_convex(cap: GeomInfo, convex: GeomInfo) -> Contact: cap_closest_pt, ) = jax.tree_map(lambda x, i=e_idx: jp.take(x, i, axis=0), res) - face_edge_normals = face_edge_normal[e_idx] - edge_voronoi_front = ((face_edge_normals @ edge_axis) < 0).all() + edge_face_normals = edge_face_normal[e_idx] + edge_voronoi_front = ((edge_face_normals @ edge_axis) < 0).all() shallow = ~degenerate_edge_dir & edge_voronoi_front edge_penetration = jp.where(shallow, cap.size[0] - edge_dist, -1) @@ -630,8 +630,9 @@ def _sat_bruteforce( We return both the edge and face contacts. Valid contacts can be checked with dist < 0. Resulting edge contacts should be preferred over face contacts. - This method checks all unique edge-pairs and is thus costly to run over large - meshes, but is more performant for smaller meshes (boxes, tetrahedra, etc.). + This method checks all separating axes via a brute force support function, and + is thus costly to run over large meshes, but is more performant for smaller + meshes (boxes, tetrahedra, etc.). Args: faces_a: Faces for hull A. @@ -731,7 +732,7 @@ def _arcs_intersect( return (cba * dba < 0) & (adc * bdc < 0) & (cba * bdc > 0) -def _sat_approx( +def _sat_gaussmap( centroid_a: jax.Array, faces_a: jax.Array, faces_b: jax.Array, @@ -739,23 +740,16 @@ def _sat_approx( vertices_b: jax.Array, normals_a: jax.Array, normals_b: jax.Array, - face_edges_a: jax.Array, - face_edges_b: jax.Array, - face_edge_normals_a: jax.Array, - face_edge_normals_b: jax.Array, + edges_a: jax.Array, + edges_b: jax.Array, + edge_face_normals_a: jax.Array, + edge_face_normals_b: jax.Array, ) -> Tuple[jax.Array, jax.Array, jax.Array]: """Runs the Separating Axis Test for a pair of hulls. - Runs the separating axis test for all faces. After obtaining a reference - and incident face, tests edge separating axes via edge intersections - on gauss maps. - - Certain meshes can have nearly parallel coplanar faces that are not merged. - Thus reference/incident faces can be non-overlapping, and face contacts will - not get generated. Since we only check edge separating axes on - reference/incident faces, the correct edge separating axes may also be - missing. We mitigate this issue by checking nearly coplanar anti-parallel - reference/incident faces for support, hence why this method is "approximate". + Runs the separating axis test for all faces. Tests edge separating axes via + edge intersections on gauss maps for all edge pairs. h/t to Dirk Gregorius + for the implementation details and gauss map trick. Args: centroid_a: Centroid of hull A. @@ -765,10 +759,10 @@ def _sat_approx( vertices_b: Vertices for hull B. normals_a: Normal vectors for hull A faces. normals_b: Normal vectors for hull B faces. - face_edges_a: Edges for faces in hull A. - face_edges_b: Edges for faces in hull B. - face_edge_normals_a: Edge normals for faces in hull A. - face_edge_normals_b: Edge normals for faces in hull B. + edges_a: Edges for hull A. + edges_b: Edges for hull B. + edge_face_normals_a: Face normals for edges in hull A. + edge_face_normals_b: Face normals for edges in hull B. Returns: tuple of dist, pos, and normal @@ -816,75 +810,61 @@ def _sat_approx( -best_axis, ) - # Handle edge separating axes by checking edge pairs on the reference and - # incident faces. In principle, the correct edge-edge separating axis can be - # created from edge pairs on the reference and incident faces. - # first get the edge directions and face edge normals - face_edges_a = face_edges_a[face_a_idx] - v_norm = jax.vmap(math.normalize) - face_edges_dir_a = v_norm(face_edges_a[:, 0] - face_edges_a[:, 1]) - face_edges_b = face_edges_b[face_b_idx] - face_edges_dir_b = v_norm(face_edges_b[:, 0] - face_edges_b[:, 1]) - face_edge_normals_a = face_edge_normals_a[face_a_idx] - face_edge_normals_b = face_edge_normals_b[face_b_idx] - - # scatter to all edge pairs - edge_idx_a = jp.repeat( - jp.arange(face_edges_a.shape[0]), face_edges_b.shape[0] + # Handle edge separating axes by checking all edge pairs. + a_idx = jp.tile(jp.arange(edges_a.shape[0]), reps=edges_b.shape[0]) + b_idx = jp.repeat( + jp.arange(edges_b.shape[0]), repeats=edges_a.shape[0], axis=0 + ) + normal_a_1 = edge_face_normals_a[a_idx, 0] + normal_a_2 = edge_face_normals_a[a_idx, 1] + normal_b_1 = edge_face_normals_b[b_idx, 0] + normal_b_2 = edge_face_normals_b[b_idx, 1] + is_minkowski_face = jax.vmap(_arcs_intersect)( + normal_a_1, normal_a_2, -normal_b_1, -normal_b_2 ) - edge_idx_b = jp.tile(jp.arange(face_edges_b.shape[0]), face_edges_a.shape[0]) - face_edges_dir_a = face_edges_dir_a[edge_idx_a] - face_edges_dir_b = face_edges_dir_b[edge_idx_b] - face_edges_pt_a = face_edges_a[:, 0][edge_idx_a] - face_edges_pt_b = face_edges_b[:, 0][edge_idx_b] - face_edge_normals_a = face_edge_normals_a[edge_idx_a] - face_edge_normals_b = face_edge_normals_b[edge_idx_b] - @jax.vmap + # get distances + edge_a_dir = jax.vmap(math.normalize)(edges_a[:, 0] - edges_a[:, 1])[a_idx] + edge_b_dir = jax.vmap(math.normalize)(edges_b[:, 0] - edges_b[:, 1])[b_idx] + edges_a, edges_b = edges_a[a_idx], edges_b[b_idx] + edge_a_pt, edge_a_pt_2 = edges_a[:, 0], edges_a[:, 1] + edge_b_pt, edge_b_pt_2 = edges_b[:, 0], edges_b[:, 1] + def get_normals(a_dir, a_pt, b_dir): - edge_axis = math.normalize(jp.cross(a_dir, b_dir)) + edge_axis = jp.cross(a_dir, b_dir) + degenerate_edge_axis = jp.sum(edge_axis**2) < 1e-6 + edge_axis = math.normalize(edge_axis) # correct normal to point from a to b, object b is at the origin sign = jp.where(jp.dot(edge_axis, a_pt - centroid_a) > 0.0, 1.0, -1.0) - return edge_axis * sign + return edge_axis * sign, degenerate_edge_axis - edge_axes = get_normals(face_edges_dir_a, face_edges_pt_a, face_edges_dir_b) - edge_dist = jax.vmap(jp.dot)(edge_axes, face_edges_pt_b - face_edges_pt_a) - # handle degenerate axes - edge_dist = jp.where((edge_axes**2).sum(axis=1) < 1e-6, 1e6, edge_dist) - # ensure edges create a minkowski face by testing intersection on gauss maps - is_minkowski_face = jax.vmap(_arcs_intersect)( - face_edge_normals_a[:, 0], - face_edge_normals_a[:, 1], - -face_edge_normals_b[:, 0], - -face_edge_normals_b[:, 1], - ) - edge_dist = jp.where(is_minkowski_face, edge_dist, 1e6) - edge_dist = jp.where(edge_dist > 0, -1e6, edge_dist) + edge_axes, degenerate_edge_axes = jax.vmap(get_normals)( + edge_a_dir, edge_a_pt, edge_b_dir) + edge_dist = jax.vmap(jp.dot)(edge_axes, edge_b_pt - edge_a_pt) + # handle degenerate axis + edge_dist = jp.where(degenerate_edge_axes, -jp.inf, edge_dist) + # ensure edges create minkowski face + edge_dist = jp.where(is_minkowski_face, edge_dist, -jp.inf) best_edge_idx = edge_dist.argmax() best_edge_dist = edge_dist[best_edge_idx] - # prefer edge over face contacts as long as we have a valid edge contact - is_edge_contact = (best_edge_dist > dist.min() + 1e-6) & (best_edge_dist < 0) - normal = jp.where(is_edge_contact, edge_axes[best_edge_idx], normal) - dist = jp.where(is_edge_contact, jp.array([best_edge_dist, 1, 1, 1]), dist) - - # A failure mode occurs if faces are very narrow and nearly parallel - # (i.e. faces did not get merged properly as coplanar faces). The face - # contacts will be empty since the reference/incident faces may not overlap. - # An edge-edge separating axis will not be found, since the reference and - # incident faces will also not overlap or necessarily create a minkowski face. - # Thus, we approximate the contact for anti-parallel faces with support. - anti_parallel = incident_face_norm.dot(ref_face_norm) < -0.97 - dist = dist.at[0].set( - jp.where( - anti_parallel - & ~is_face_separating - & (dist > 0).all() - & ~is_edge_contact, - -support[best_idx], - dist[0], - ) + is_edge_contact = jp.where( + dist.max() < 0, best_edge_dist > dist.max() - 1e-6, + (best_edge_dist < 0) & ~jp.isinf(best_edge_dist) ) + is_edge_contact = is_edge_contact & ~is_face_separating + normal = jp.where(is_edge_contact, edge_axes[best_edge_idx], normal) + dist = jp.where( + is_edge_contact, + jp.array([best_edge_dist, 1, 1, 1]), + dist, + ) + a_closest, b_closest = math.closest_segment_to_segment_points( + edge_a_pt[best_edge_idx], edge_a_pt_2[best_edge_idx], + edge_b_pt[best_edge_idx], edge_b_pt_2[best_edge_idx]) + pos = jp.where( + is_edge_contact, + jp.tile(0.5 * (a_closest + b_closest), (4, 1)), pos) return dist, pos, normal @@ -924,15 +904,15 @@ def convex_convex(c1: GeomInfo, c2: GeomInfo) -> Contact: unique_edges1 = jp.take(vertices1, c1.edge, axis=0) unique_edges2 = jp.take(vertices2, c2.edge, axis=0) - face_edges1 = jp.take(vertices1, c1.face_edge, axis=0) - face_edges2 = jp.take(vertices2, c2.face_edge, axis=0) + edges1 = jp.take(vertices1, c1.edge, axis=0) + edges2 = jp.take(vertices2, c2.edge, axis=0) - face_edge_normals1 = c1.face_edge_normal @ to_local_mat.T - face_edge_normals2 = c2.face_edge_normal + edge_face_normals1 = c1.edge_face_normal @ to_local_mat.T + edge_face_normals2 = c2.edge_face_normal enable_bruteforce = ( unique_edges1.shape[0] * unique_edges2.shape[0] - < face_edges1[0].shape[0] * face_edges2[0].shape[0] + < edges1[0].shape[0] * edges2[0].shape[0] ) if enable_bruteforce: dist, pos, normal = _sat_bruteforce( @@ -946,7 +926,7 @@ def convex_convex(c1: GeomInfo, c2: GeomInfo) -> Contact: unique_edges2, ) else: - dist, pos, normal = _sat_approx( + dist, pos, normal = _sat_gaussmap( to_local_pos, faces1, faces2, @@ -954,10 +934,10 @@ def convex_convex(c1: GeomInfo, c2: GeomInfo) -> Contact: vertices2, normals1, normals2, - face_edges1, - face_edges2, - face_edge_normals1, - face_edge_normals2, + edges1, + edges2, + edge_face_normals1, + edge_face_normals2, ) # Go back to world frame. diff --git a/mjx/mujoco/mjx/_src/collision_driver.py b/mjx/mujoco/mjx/_src/collision_driver.py index 3b70990c..8fa56612 100644 --- a/mjx/mujoco/mjx/_src/collision_driver.py +++ b/mjx/mujoco/mjx/_src/collision_driver.py @@ -230,20 +230,20 @@ def _pair_info( info = info.replace( face=jp.stack([m.geom_convex_face[i] for i in geom]), vert=jp.stack([m.geom_convex_vert[i] for i in geom]), - edge=jp.stack([m.geom_convex_edge_dir[i] for i in geom]), + edge_dir=jp.stack([m.geom_convex_edge_dir[i] for i in geom]), facenorm=jp.stack([m.geom_convex_facenormal[i] for i in geom]), - face_edge_normal=jp.stack( - [m.geom_convex_face_edge_normal[i] for i in geom] + edge=jp.stack([m.geom_convex_edge[i] for i in geom]), + edge_face_normal=jp.stack( + [m.geom_convex_edge_face_normal[i] for i in geom] ), - face_edge=jp.stack([m.geom_convex_face_edge[i] for i in geom]), ) in_axes = in_axes.replace( face=0, vert=0, - edge=0, + edge_dir=0, facenorm=0, - face_edge=0, - face_edge_normal=0, + edge=0, + edge_face_normal=0, ) return info, in_axes diff --git a/mjx/mujoco/mjx/_src/collision_driver_test.py b/mjx/mujoco/mjx/_src/collision_driver_test.py index 0093f7f3..acb52e12 100644 --- a/mjx/mujoco/mjx/_src/collision_driver_test.py +++ b/mjx/mujoco/mjx/_src/collision_driver_test.py @@ -527,7 +527,7 @@ class ConvexTest(absltest.TestCase): """ def test_convex_convex(self): - """Tests generic convex-convex collision via _sat_approx.""" + """Tests generic convex-convex collision via _sat_gaussmap.""" directory = epath.resource_path('mujoco.mjx') assets = { 'meshes/dodecahedron.stl': ( @@ -542,6 +542,44 @@ class ConvexTest(absltest.TestCase): np.testing.assert_array_less(0, c.dist[1:]) np.testing.assert_array_almost_equal(c.frame[0, 0], np.array([0, 0, 1])) + _CONVEX_CONVEX_THIN = """ + + + + + + + + + + + + + + + + """ + + def test_convex_convex_edge(self): + """Tests convex-convex collisions with edge contact via _sat_gaussmap.""" + _, dx = _collide(self._CONVEX_CONVEX_THIN) + c = dx.contact + + # Only one contact point for an edge contact. + self.assertLess(c.dist[0], 0) + np.testing.assert_array_less(0, c.dist[1:]) + np.testing.assert_array_almost_equal(c.frame[0, 0], np.array([0, 0, 1])) + np.testing.assert_array_almost_equal( + c.pos[0], np.array([0, 2, 1.3155]), decimal=5) + + _, dx = _collide( + self._CONVEX_CONVEX_THIN.replace( + 'pos="0.0 2.0 0.35"', 'pos="0.0 2.0 0"')) + c = dx.contact + self.assertTrue((c.dist > 0).all()) + class BodyPairFilterTest(absltest.TestCase): """Tests that certain body pairs get filtered.""" @@ -647,11 +685,11 @@ class NconTest(parameterized.TestCase): m.numeric_data[m.numeric_adr[i]] = -1 ncon = collision_driver.ncon(m) - self.assertEqual(ncon, 307) + self.assertEqual(ncon, 98) mx = mjx.put_model(m) ncon = collision_driver.ncon(mx) - self.assertEqual(ncon, 307) + self.assertEqual(ncon, 98) class TopKContactTest(absltest.TestCase): diff --git a/mjx/mujoco/mjx/_src/mesh.py b/mjx/mujoco/mjx/_src/mesh.py index 13af828f..39151edf 100644 --- a/mjx/mujoco/mjx/_src/mesh.py +++ b/mjx/mujoco/mjx/_src/mesh.py @@ -49,8 +49,8 @@ _DERIVED_ARGS = [ 'geom_convex_vert', 'geom_convex_edge_dir', 'geom_convex_facenormal', - 'geom_convex_face_edge', - 'geom_convex_face_edge_normal', + 'geom_convex_edge', + 'geom_convex_edge_face_normal', ] DERIVED = {(Model, d) for d in _DERIVED_ARGS} @@ -114,7 +114,7 @@ def _get_unique_edge_dir(vert: np.ndarray, face: np.ndarray) -> np.ndarray: return edges[unique_edge_idx] -def _get_face_edge_normals( +def _get_edge_normals( face: np.ndarray, face_norm: np.ndarray ) -> Tuple[np.ndarray, np.ndarray]: """Returns face edges and face edge normals.""" @@ -133,7 +133,7 @@ def _get_face_edge_normals( continue edge_map_list[tuple(face_edge_flat[i])].append(edge_face_norm[i]) - edge_map = {} + edges, edge_face_normals = [], [] for k, v in edge_map_list.items(): v = np.array(v) if len(v) > 2: @@ -145,19 +145,10 @@ def _get_face_edge_normals( # and face vertices were down sampled. In either case, we ignore these # edges. continue - edge_map[k] = v + edges.append(k) + edge_face_normals.append(v) - # for each face, list the edge normals - face_edge_normal = [] - for face_idx in range(face_edge.shape[0]): - normals = [] - for edge in face_edge[face_idx]: - k = tuple(edge) - normals.append(edge_map.get(k, np.zeros((2, 3)))) - face_edge_normal.append(np.array(normals)) - face_edge_normal = np.array(face_edge_normal) - - return face_edge, face_edge_normal + return np.array(edges), np.array(edge_face_normals) def _convex_hull_2d(points: np.ndarray, normal: np.ndarray) -> np.ndarray: @@ -297,15 +288,15 @@ def _geom_mesh_kwargs( vert = np.array(tm_convex.vertices) face = _merge_coplanar(tm_convex, mesh_info) facenormal = _get_face_norm(vert, face) - face_edge, face_edge_normal = _get_face_edge_normals(face, facenormal) + edge, edge_face_normal = _get_edge_normals(face, facenormal) return { 'geom_convex_face': vert[face], 'geom_convex_face_vert_idx': face, 'geom_convex_vert': vert, 'geom_convex_edge_dir': _get_unique_edge_dir(vert, face), 'geom_convex_facenormal': facenormal, - 'geom_convex_face_edge': face_edge, - 'geom_convex_face_edge_normal': face_edge_normal, + 'geom_convex_edge': edge, + 'geom_convex_edge_face_normal': edge_face_normal, } diff --git a/mjx/mujoco/mjx/_src/mesh_test.py b/mjx/mujoco/mjx/_src/mesh_test.py index 233f3baa..266a81f0 100644 --- a/mjx/mujoco/mjx/_src/mesh_test.py +++ b/mjx/mujoco/mjx/_src/mesh_test.py @@ -80,7 +80,7 @@ class GeomMeshKwargsTest(absltest.TestCase): self.assertEqual(h['geom_convex_facenormal'].shape, (5, 3)) # face edges - edges = np.concatenate(h['geom_convex_face_edge']) + edges = h['geom_convex_edge'] edges = np.vectorize(map_.get)(edges) mask = edges[:, 0] != edges[:, 1] edges = edges[mask] @@ -92,27 +92,18 @@ class GeomMeshKwargsTest(absltest.TestCase): edges, np.array([ [0, 2], - [0, 2], - [0, 3], [0, 3], [0, 4], - [0, 4], - [1, 2], [1, 2], [1, 3], - [1, 3], - [1, 4], [1, 4], [2, 4], - [2, 4], - [3, 4], [3, 4], ]), ) # face edge normals - edge_normal = h['geom_convex_face_edge_normal'] - edge_normal = np.concatenate(edge_normal) + edge_normal = h['geom_convex_edge_face_normal'] edge_normal = edge_normal[mask] edge_normal = np.take_along_axis( edge_normal, sort_col_idx[..., None], axis=1 @@ -120,8 +111,8 @@ class GeomMeshKwargsTest(absltest.TestCase): edge_normal = edge_normal[sort_row_idx] edge_normal_02 = np.array([[0.4472136, -0.0, 0.89442719], [-1.0, 0.0, 0.0]]) np.testing.assert_array_almost_equal( - edge_normal[:2], - np.array([edge_normal_02, edge_normal_02]), + edge_normal[:1], + np.array([edge_normal_02]), ) diff --git a/mjx/mujoco/mjx/_src/types.py b/mjx/mujoco/mjx/_src/types.py index 92b04a72..97870a40 100644 --- a/mjx/mujoco/mjx/_src/types.py +++ b/mjx/mujoco/mjx/_src/types.py @@ -543,8 +543,8 @@ class Model(PyTreeNode): geom_convex_vert: List[Optional[jax.Array]] geom_convex_edge_dir: List[Optional[jax.Array]] geom_convex_facenormal: List[Optional[jax.Array]] - geom_convex_face_edge: List[Optional[jax.Array]] - geom_convex_face_edge_normal: List[Optional[jax.Array]] + geom_convex_edge: List[Optional[jax.Array]] + geom_convex_edge_face_normal: List[Optional[jax.Array]] pair_solref: jax.Array pair_solreffriction: jax.Array pair_solimp: jax.Array diff --git a/mjx/mujoco/mjx/test_data/shadow_hand/right_hand.xml b/mjx/mujoco/mjx/test_data/shadow_hand/right_hand.xml index 13bc5435..ba1a2f34 100644 --- a/mjx/mujoco/mjx/test_data/shadow_hand/right_hand.xml +++ b/mjx/mujoco/mjx/test_data/shadow_hand/right_hand.xml @@ -156,7 +156,7 @@ diaginertia="1.28092e-06 1.12092e-06 5.3e-07"/> - + @@ -181,7 +181,7 @@ diaginertia="1.28092e-06 1.12092e-06 5.3e-07"/> - + @@ -206,7 +206,7 @@ diaginertia="1.28092e-06 1.12092e-06 5.3e-07"/> - + @@ -236,7 +236,7 @@ diaginertia="1.28092e-06 1.12092e-06 5.3e-07"/> - + @@ -266,7 +266,7 @@ diaginertia="2.37794e-06 2.27794e-06 1e-06"/> - + From 47ba72ea59a40be1e7e03765de91d8ec51f24d22 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Thu, 28 Mar 2024 14:00:55 -0700 Subject: [PATCH 46/51] Add `actuatorgravcomp` joint attribute, to treat gravity compensation forces as applied by actuators, rather than passive buoyancy. PiperOrigin-RevId: 620049593 Change-Id: I2c8a9dc152c087b408e4f904838034271a7dd910 --- doc/XMLreference.rst | 68 ++++++++++++-------- doc/XMLschema.rst | 10 +-- doc/changelog.rst | 45 +++++++------ doc/includes/references.h | 7 +- include/mujoco/mjmodel.h | 7 +- include/mujoco/mjxmacro.h | 1 + introspect/structs.py | 13 +++- src/engine/engine_forward.c | 48 ++++++++++++-- src/engine/engine_passive.c | 33 +++++++++- src/user/user_api.h | 1 + src/user/user_model.cc | 1 + src/xml/xml_native_reader.cc | 14 ++-- src/xml/xml_native_writer.cc | 1 + test/engine/engine_forward_test.cc | 74 ++++++++++++++++++++++ test/engine/testdata/actuation/refsite.xml | 12 ++-- unity/Runtime/Bindings/MjBindings.cs | 1 + 16 files changed, 257 insertions(+), 79 deletions(-) diff --git a/doc/XMLreference.rst b/doc/XMLreference.rst index e9bbde58..81bb0c3d 100644 --- a/doc/XMLreference.rst +++ b/doc/XMLreference.rst @@ -2354,24 +2354,6 @@ rotations as unit quaternions. joint inertia in the model reference configuration. Note that the format is the same as the solref parameter of the constraint solver. -.. _body-joint-limited: - -:at:`limited`: :at-val:`[false, true, auto], "auto"` - This attribute specifies if the joint has limits. It interacts with the range attribute below. If this attribute - is "false", joint limits are disabled. If this attribute is "true", joint limits are enabled. If this - attribute is "auto", and :at:`autolimits` is set in :ref:`compiler `, joint limits will be enabled - if range is defined. - -.. _body-joint-actuatorfrclimited: - -:at:`actuatorfrclimited`: :at-val:`[false, true, auto], "auto"` - This attribute specifies whether actuator forces acting on the joint should be clamped. See :ref:`CForceRange` for - details. It is available only for scalar joints (hinge and slider) and ignored for ball and free joints. |br| This - attribute interacts with the actuatorfrcrange attribute below. If this attribute is "false", actuator force - clamping is disabled. If it is "true", actuator force clamping is enabled. If this attribute is "auto", and - :at:`autolimits` is set in :ref:`compiler `, actuator force clamping will be enabled if actuatorfrcrange - is defined. - .. _body-joint-solreflimit: .. _body-joint-solimplimit: @@ -2400,16 +2382,44 @@ rotations as unit quaternions. joints, the limit is imposed on the angle of rotation (relative to the reference configuration) regardless of the axis of rotation. Only the second range parameter is used for ball joints; the first range parameter should be set to 0. See the :ref:`Limit ` section in the Computation chapter for more information. - |br| Setting this attribute without specifying :at:`limited` is an error, unless :at:`autolimits` is set in + |br| Setting this attribute without specifying :at:`limited` is an error if :at:`autolimits` is "false" in :ref:`compiler `. +.. _body-joint-limited: + +:at:`limited`: :at-val:`[false, true, auto], "auto"` + This attribute specifies if the joint has limits. It interacts with the range attribute below. If this attribute + is "false", joint limits are disabled. If this attribute is "true", joint limits are enabled. If this + attribute is "auto", and :at:`autolimits` is set in :ref:`compiler `, joint limits will be enabled + if range is defined. + .. _body-joint-actuatorfrcrange: :at:`actuatorfrcrange`: :at-val:`real(2), "0 0"` Range for clamping total actuator forces acting on this joint. See :ref:`CForceRange` for details. It is available only for scalar joints (hinge and slider) and ignored for ball and free joints. |br| The compiler expects the first value to be smaller than the second value. |br| Setting this attribute without specifying :at:`actuatorfrclimited` - is an error, unless :at:`compiler-autolimits` is set. + is an error if :at:`compiler-autolimits` is "false". + +.. _body-joint-actuatorfrclimited: + +:at:`actuatorfrclimited`: :at-val:`[false, true, auto], "auto"` + This attribute specifies whether actuator forces acting on the joint should be clamped. See :ref:`CForceRange` for + details. It is available only for scalar joints (hinge and slider) and ignored for ball and free joints. |br| This + attribute interacts with the actuatorfrcrange attribute below. If this attribute is "false", actuator force + clamping is disabled. If it is "true", actuator force clamping is enabled. If this attribute is "auto", and + :at:`autolimits` is set in :ref:`compiler `, actuator force clamping will be enabled if + :at:`actuatorfrcrange` is defined. + +.. _body-joint-actuatorgravcomp: + +:at:`actuatorgravcomp`: :at-val:`[false, true], "false"` + If this flag is enabled, gravity compensation applied to this joint is added to actuator forces + (``mjData.qfrc_actuator``) rather than passive forces (``mjData.qfrc_passive``). Notionally, this means that gravity + compensation is the result of a control system rather than natural buoyancy. In practice, enabling this flag is + useful when joint-level actuator force clamping is used. In this case, the total actuation force applied on a joint, + including gravity compensation, is guaranteed to not exceeed the specified limits. See :ref:`CForceRange` and + :ref:`actuatorfrcrange` for more details on this type of force limit. .. _body-joint-margin: @@ -5096,14 +5106,14 @@ specify them independently. :at:`ctrlrange`: :at-val:`real(2), "0 0"` Range for clamping the control input. The first value must be smaller than the second value. - |br| Setting this attribute without specifying :at:`ctrllimited` is an error, unless :at:`autolimits` is set in + |br| Setting this attribute without specifying :at:`ctrllimited` is an error if :at:`autolimits` is "false" in :ref:`compiler `. .. _actuator-general-forcerange: :at:`forcerange`: :at-val:`real(2), "0 0"` Range for clamping the force output. The first value must be no greater than the second value. - |br| Setting this attribute without specifying :at:`forcelimited` is an error, unless :at:`autolimits` is set in + |br| Setting this attribute without specifying :at:`forcelimited` is an error if :at:`autolimits` is "false" in :ref:`compiler `. .. _actuator-general-actrange: @@ -5111,7 +5121,7 @@ specify them independently. :at:`actrange`: :at-val:`real(2), "0 0"` Range for clamping the activation state. The first value must be no greater than the second value. See the :ref:`Activation clamping ` section for more details. - |br| Setting this attribute without specifying :at:`actlimited` is an error, unless :at:`autolimits` is set in + |br| Setting this attribute without specifying :at:`actlimited` is an error if :at:`autolimits` is "false" in :ref:`compiler `. .. _actuator-general-lengthrange: @@ -6489,10 +6499,12 @@ arms determined by the transmission). This sensor can be attached to any actuato :el-prefix:`sensor/` |-| **jointactuatorfrc** (*) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -This element creates an actuator force sensor, measured at a joint. The quantity being sensed is the -generalized force contributed by all actuators to a single scalar joint (hinge or slider). This type of sensor is -important when multiple actuators act on a single joint or when a single actuator act on multiple joints. See -:ref:`CForceRange` for details. +This element creates an actuator force sensor, measured at a joint. The quantity being sensed is the generalized force +contributed by all actuators to a single scalar joint (hinge or slider). If the joint's +:ref:`actuatorgravcomp` attribute is "true", this sensor will also measure contributions by +gravity compensation forces (which are added directly to the joint and would *not* register in the +:ref:`actuatorfrc`) sensor. This type of sensor is important when multiple actuators act on a single +joint or when a single actuator act on multiple joints. See :ref:`CForceRange` for details. .. _sensor-jointactuatorfrc-name: @@ -7386,6 +7398,8 @@ if omitted. .. _default-joint-actuatorfrclimited: +.. _default-joint-actuatorgravcomp: + .. _default-joint-solreflimit: .. _default-joint-solimplimit: diff --git a/doc/XMLschema.rst b/doc/XMLschema.rst index 03a651af..3327930d 100644 --- a/doc/XMLschema.rst +++ b/doc/XMLschema.rst @@ -286,9 +286,9 @@ | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | | :ref:`solimpfriction` | :ref:`stiffness` | :ref:`range` | :ref:`actuatorfrcrange` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`margin` | :ref:`ref` | :ref:`springref` | :ref:`armature` | | +| | | | :ref:`actuatorgravcomp` | :ref:`margin` | :ref:`ref` | :ref:`springref` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`damping` | :ref:`frictionloss` | :ref:`user` | | | +| | | | :ref:`armature` | :ref:`damping` | :ref:`frictionloss` | :ref:`user` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | |_| body |br| |_| |L| | | .. table:: | @@ -1320,11 +1320,11 @@ | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | | :ref:`solimplimit` | :ref:`solreffriction` | :ref:`solimpfriction` | :ref:`stiffness` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`range` | :ref:`actuatorfrcrange` | :ref:`margin` | :ref:`ref` | | +| | | | :ref:`range` | :ref:`actuatorfrcrange` | :ref:`actuatorgravcomp` | :ref:`margin` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`springref` | :ref:`armature` | :ref:`damping` | :ref:`frictionloss` | | +| | | | :ref:`ref` | :ref:`springref` | :ref:`armature` | :ref:`damping` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`user` | | | | | +| | | | :ref:`frictionloss` | :ref:`user` | | | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | |_| default |br| |_| |L| | | .. table:: | diff --git a/doc/changelog.rst b/doc/changelog.rst index 940f74f2..027d3221 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -7,15 +7,35 @@ Upcoming version (not yet released) General ^^^^^^^ -1. Added support for gmsh format 2.2, as generated by e.g. `fTetwild `__. +1. Added the :ref:`actuatorgravcomp` joint attribute. When enabled, gravity compensation + forces on the joint are treated as applied by actuators. See attribute documentation for more details. The example + model + `refsite.xml `__, + which demostrates Cartesian actuation of an arm, has been updated to use this attribute. +2. Added support for gmsh format 2.2, as generated by e.g. `fTetwild `__. MJX ^^^ +3. Improved performance of SAT for convex collisions. +4. Fixed bug for sphere/capsule-convex deep penetration. +5. Fixed bug where ``mjx.Data`` produced by ``mjx.put_data`` had different treedef than ``mjx.make_data``. +6. Throw an error for margin/gap for convex mesh collisions, since they are not supported. + +Simulate +^^^^^^^^ +7. Fixed bug in order of enable flag strings. Before this change, using the simulate UI to toggle the + :ref:`invdiscrete` or :ref:`sensornoise` + flags would actually toggle the other flag. + +Python bindings +^^^^^^^^^^^^^^^ +8. Added the ``mujoco.minimize`` Python module for nonlinear least-squares, designed for System Identification (sysID). + The sysID tutorial is work in progress, but a pedagogical colab notebook with examples, including Inverse + Kinematics, is available here: |ls_colab| + +.. |ls_colab| image:: https://colab.research.google.com/assets/colab-badge.svg + :target: https://colab.research.google.com/github/google-deepmind/mujoco/blob/main/python/least_squares.ipynb -2. Improved performance of SAT for convex collisions. -3. Fixed bug for sphere/capsule-convex deep penetration. -4. Fixed bug where ``mjx.Data`` produced by ``mjx.put_data`` had different treedef than ``mjx.make_data``. -5. Throw an error for margin/gap for convex mesh collisions, since they are not supported. Version 3.1.3 (March 5th, 2024) ------------------------------- @@ -37,7 +57,6 @@ General MJX ^^^ - 4. Improved performance of getting and putting device data. - Use ``tobytes()`` for numpy array serialization, which is orders of magnitude faster than converting to tuples. @@ -56,21 +75,9 @@ Python bindings ^^^^^^^^^^^^^^^ 11. Fixed incorrect data types in the bindings for the ``geom``, ``vert``, ``elem``, and ``flex`` array members of the ``mjContact`` struct, and all array members of the ``mjrContext`` struct. -12. Added the ``mujoco.minimize`` Python module for nonlinear least-squares, designed for System Identification (sysID). - The sysID tutorial is work in progress, but a pedagogical colab notebook with examples, including Inverse - Kinematics, is available here: |ls_colab| - -.. |ls_colab| image:: https://colab.research.google.com/assets/colab-badge.svg - :target: https://colab.research.google.com/github/google-deepmind/mujoco/blob/main/python/least_squares.ipynb - -Simulate -^^^^^^^^ -13. Fixed bug in order of enable flag strings. Before this change, using the simulate UI to toggle the - :ref:`invdiscrete` or :ref:`sensornoise` - flags would actually toggle the other flag. Version 3.1.2 (February 05, 2024) ------------------------------------ +--------------------------------- General ^^^^^^^ diff --git a/doc/includes/references.h b/doc/includes/references.h index 6fd2a650..8bb4ee1a 100644 --- a/doc/includes/references.h +++ b/doc/includes/references.h @@ -926,9 +926,9 @@ struct mjModel_ { int nemax; // number of potential equality-constraint rows int njmax; // number of available rows in constraint Jacobian int nconmax; // number of potential contacts in contact list - int nuserdata; // number of extra fields in mjData - int nsensordata; // number of fields in sensor data vector - int npluginstate; // number of fields in plugin state vector + int nuserdata; // number of mjtNums reserved for the user + int nsensordata; // number of mjtNums in sensor data vector + int npluginstate; // number of mjtNums in plugin state vector size_t narena; // number of bytes in the mjData arena (inclusive of stack) size_t nbuffer; // number of bytes in buffer @@ -993,6 +993,7 @@ struct mjModel_ { int* jnt_group; // group for visibility (njnt x 1) mjtByte* jnt_limited; // does joint have limits (njnt x 1) mjtByte* jnt_actfrclimited; // does joint have actuator force limits (njnt x 1) + mjtByte* jnt_actgravcomp; // is gravcomp force applied via actuators (njnt x 1) mjtNum* jnt_solref; // constraint solver reference: limit (njnt x mjNREF) mjtNum* jnt_solimp; // constraint solver impedance: limit (njnt x mjNIMP) mjtNum* jnt_pos; // local anchor position (njnt x 3) diff --git a/include/mujoco/mjmodel.h b/include/mujoco/mjmodel.h index 15840a82..f4c480c6 100644 --- a/include/mujoco/mjmodel.h +++ b/include/mujoco/mjmodel.h @@ -641,9 +641,9 @@ struct mjModel_ { int nemax; // number of potential equality-constraint rows int njmax; // number of available rows in constraint Jacobian int nconmax; // number of potential contacts in contact list - int nuserdata; // number of extra fields in mjData - int nsensordata; // number of fields in sensor data vector - int npluginstate; // number of fields in plugin state vector + int nuserdata; // number of mjtNums reserved for the user + int nsensordata; // number of mjtNums in sensor data vector + int npluginstate; // number of mjtNums in plugin state vector size_t narena; // number of bytes in the mjData arena (inclusive of stack) size_t nbuffer; // number of bytes in buffer @@ -708,6 +708,7 @@ struct mjModel_ { int* jnt_group; // group for visibility (njnt x 1) mjtByte* jnt_limited; // does joint have limits (njnt x 1) mjtByte* jnt_actfrclimited; // does joint have actuator force limits (njnt x 1) + mjtByte* jnt_actgravcomp; // is gravcomp force applied via actuators (njnt x 1) mjtNum* jnt_solref; // constraint solver reference: limit (njnt x mjNREF) mjtNum* jnt_solimp; // constraint solver impedance: limit (njnt x mjNIMP) mjtNum* jnt_pos; // local anchor position (njnt x 3) diff --git a/include/mujoco/mjxmacro.h b/include/mujoco/mjxmacro.h index a46aea71..7cb4fa7b 100644 --- a/include/mujoco/mjxmacro.h +++ b/include/mujoco/mjxmacro.h @@ -215,6 +215,7 @@ XMJV( int, jnt_group, njnt, 1 ) \ X ( mjtByte, jnt_limited, njnt, 1 ) \ X ( mjtByte, jnt_actfrclimited, njnt, 1 ) \ + X ( mjtByte, jnt_actgravcomp, njnt, 1 ) \ X ( mjtNum, jnt_solref, njnt, mjNREF ) \ X ( mjtNum, jnt_solimp, njnt, mjNIMP ) \ X ( mjtNum, jnt_pos, njnt, 3 ) \ diff --git a/introspect/structs.py b/introspect/structs.py index 67c44261..980a9f0f 100644 --- a/introspect/structs.py +++ b/introspect/structs.py @@ -1218,17 +1218,17 @@ STRUCTS: Mapping[str, StructDecl] = dict([ StructFieldDecl( name='nuserdata', type=ValueType(name='int'), - doc='number of extra fields in mjData', + doc='number of mjtNums reserved for the user', ), StructFieldDecl( name='nsensordata', type=ValueType(name='int'), - doc='number of fields in sensor data vector', + doc='number of mjtNums in sensor data vector', ), StructFieldDecl( name='npluginstate', type=ValueType(name='int'), - doc='number of fields in plugin state vector', + doc='number of mjtNums in plugin state vector', ), StructFieldDecl( name='narena', @@ -1556,6 +1556,13 @@ STRUCTS: Mapping[str, StructDecl] = dict([ ), doc='does joint have actuator force limits (njnt x 1)', ), + StructFieldDecl( + name='jnt_actgravcomp', + type=PointerType( + inner_type=ValueType(name='mjtByte'), + ), + doc='is gravcomp force applied via actuators (njnt x 1)', + ), StructFieldDecl( name='jnt_solref', type=PointerType( diff --git a/src/engine/engine_forward.c b/src/engine/engine_forward.c index bcaa55ff..8275f751 100644 --- a/src/engine/engine_forward.c +++ b/src/engine/engine_forward.c @@ -244,7 +244,7 @@ static mjtNum nextActivation(const mjModel* m, const mjData* d, // clamp vector to range -static void mju_clamp(mjtNum* vec, const mjtNum* range, const mjtByte* limited, int n, +static void clampVec(mjtNum* vec, const mjtNum* range, const mjtByte* limited, int n, const int* index) { for (int i=0; i < n; i++) { int j = index ? index[i] : i; @@ -277,7 +277,7 @@ void mj_fwdActuation(const mjModel* m, mjData* d) { mjtNum *ctrl = mj_stackAllocNum(d, nu); mju_copy(ctrl, d->ctrl, nu); if (!mjDISABLED(mjDSBL_CLAMPCTRL)) { - mju_clamp(ctrl, m->actuator_ctrlrange, m->actuator_ctrllimited, nu, NULL); + clampVec(ctrl, m->actuator_ctrlrange, m->actuator_ctrllimited, nu, NULL); } // check controls, set all to 0 if any are bad @@ -463,13 +463,47 @@ void mj_fwdActuation(const mjModel* m, mjData* d) { } // clamp actuator_force - mju_clamp(force, m->actuator_forcerange, m->actuator_forcelimited, nu, NULL); + clampVec(force, m->actuator_forcerange, m->actuator_forcelimited, nu, NULL); // qfrc_actuator = moment' * force mju_mulMatTVec(d->qfrc_actuator, moment, force, nu, nv); - // clamp qfrc_actuator - mju_clamp(d->qfrc_actuator, m->jnt_actfrcrange, m->jnt_actfrclimited, m->njnt, m->jnt_dofadr); + // actuator-level gravity compensation + if (!mjDISABLED(mjDSBL_GRAVITY) && mju_norm3(m->opt.gravity)) { + int njnt = m->njnt; + for (int i=0; i < njnt; i++) { + // skip if gravcomp added as passive force + if (!m->jnt_actgravcomp[i]) { + continue; + } + + // get number of dofs for this joint + int dofnum; + switch (m->jnt_type[i]) { + case mjJNT_HINGE: + case mjJNT_SLIDE: + dofnum = 1; + break; + + case mjJNT_BALL: + dofnum = 3; + break; + + case mjJNT_FREE: + dofnum = 6; + break; + } + + // add gravcomp force + int dofadr = m->jnt_dofadr[i]; + for (int j=0; j < dofnum; j++) { + d->qfrc_actuator[dofadr+j] += d->qfrc_gravcomp[dofadr+j]; + } + } + } + + // clamp qfrc_actuator to joint-level actuator force limits + clampVec(d->qfrc_actuator, m->jnt_actfrcrange, m->jnt_actfrclimited, m->njnt, m->jnt_dofadr); mj_freeStack(d); TM_END(mjTIMER_ACTUATION); @@ -481,13 +515,13 @@ void mj_fwdActuation(const mjModel* m, mjData* d) { void mj_fwdAcceleration(const mjModel* m, mjData* d) { int nv = m->nv; - // qforce = sum of all non-constraint forces + // qfrc_smooth = sum of all non-constraint forces mju_sub(d->qfrc_smooth, d->qfrc_passive, d->qfrc_bias, nv); // qfrc_bias is negative mju_addTo(d->qfrc_smooth, d->qfrc_applied, nv); mju_addTo(d->qfrc_smooth, d->qfrc_actuator, nv); mj_xfrcAccumulate(m, d, d->qfrc_smooth); - // qacc_smooth = M \ qfr_smooth + // qacc_smooth = M \ qfrc_smooth mj_solveM(m, d, d->qacc_smooth, d->qfrc_smooth, 1); } diff --git a/src/engine/engine_passive.c b/src/engine/engine_passive.c index 4b714527..6df4ef23 100644 --- a/src/engine/engine_passive.c +++ b/src/engine/engine_passive.c @@ -255,8 +255,39 @@ void mj_passive(const mjModel* m, mjData* d) { // add passive forces into qfrc_passive mju_add(d->qfrc_passive, d->qfrc_spring, d->qfrc_damper, nv); - if (has_gravcomp) mju_addTo(d->qfrc_passive, d->qfrc_gravcomp, nv); if (has_fluid) mju_addTo(d->qfrc_passive, d->qfrc_fluid, nv); + if (has_gravcomp) { + int njnt = m->njnt; + for (int i=0; i < njnt; i++) { + // skip if gravcomp added via actuators + if (m->jnt_actgravcomp[i]) { + continue; + } + + // get number of dofs for this joint + int dofnum; + switch (m->jnt_type[i]) { + case mjJNT_HINGE: + case mjJNT_SLIDE: + dofnum = 1; + break; + + case mjJNT_BALL: + dofnum = 3; + break; + + case mjJNT_FREE: + dofnum = 6; + break; + } + + // add gravcomp force + int dofadr = m->jnt_dofadr[i]; + for (int j=0; j < dofnum; j++) { + d->qfrc_passive[dofadr+j] += d->qfrc_gravcomp[dofadr+j]; + } + } + } // user callback: add custom passive forces if (mjcb_passive) { diff --git a/src/user/user_api.h b/src/user/user_api.h index b448f3e4..c12a4e4c 100644 --- a/src/user/user_api.h +++ b/src/user/user_api.h @@ -230,6 +230,7 @@ typedef struct _mjsJoint { // joint specification // other int group; // group + mjtByte actgravcomp; // is gravcomp force applied via actuators double urdfeffort; // effort (urdf) mjDoubleVec userdata; // user data mjString info; // message appended to compiler errors diff --git a/src/user/user_model.cc b/src/user/user_model.cc index 0217359c..c80077be 100644 --- a/src/user/user_model.cc +++ b/src/user/user_model.cc @@ -1768,6 +1768,7 @@ void mjCModel::CopyTree(mjModel* m) { m->jnt_group[jid] = pj->group; m->jnt_limited[jid] = (mjtByte)pj->is_limited(); m->jnt_actfrclimited[jid] = (mjtByte)pj->is_actfrclimited(); + m->jnt_actgravcomp[jid] = pj->actgravcomp; m->jnt_qposadr[jid] = qposadr; m->jnt_dofadr[jid] = dofadr; m->jnt_bodyid[jid] = pj->body->id; diff --git a/src/xml/xml_native_reader.cc b/src/xml/xml_native_reader.cc index 48f5547f..11811c2b 100644 --- a/src/xml/xml_native_reader.cc +++ b/src/xml/xml_native_reader.cc @@ -138,10 +138,11 @@ const char* MJCF[nMJCF][mjXATTRNUM] = { {"mesh", "?", "1", "scale"}, {"material", "?", "8", "texture", "emission", "specular", "shininess", "reflectance", "rgba", "texrepeat", "texuniform"}, - {"joint", "?", "21", "type", "group", "pos", "axis", "springdamper", + {"joint", "?", "22", "type", "group", "pos", "axis", "springdamper", "limited", "actuatorfrclimited", "solreflimit", "solimplimit", "solreffriction", "solimpfriction", "stiffness", "range", "actuatorfrcrange", - "margin", "ref", "springref", "armature", "damping", "frictionloss", "user"}, + "actuatorgravcomp", "margin", "ref", "springref", "armature", "damping", + "frictionloss", "user"}, {"geom", "?", "31", "type", "pos", "quat", "contype", "conaffinity", "condim", "group", "priority", "size", "material", "friction", "mass", "density", "shellinertia", "solmix", "solref", "solimp", @@ -240,11 +241,11 @@ const char* MJCF[nMJCF][mjXATTRNUM] = { {"<"}, {"inertial", "?", "9", "pos", "quat", "mass", "diaginertia", "axisangle", "xyaxes", "zaxis", "euler", "fullinertia"}, - {"joint", "*", "23", "name", "class", "type", "group", "pos", "axis", + {"joint", "*", "24", "name", "class", "type", "group", "pos", "axis", "springdamper", "limited", "actuatorfrclimited", "solreflimit", "solimplimit", "solreffriction", "solimpfriction", - "stiffness", "range", "actuatorfrcrange", "margin", "ref", "springref", - "armature", "damping", "frictionloss", "user"}, + "stiffness", "range", "actuatorfrcrange", "actuatorgravcomp", "margin", "ref", + "springref", "armature", "damping", "frictionloss", "user"}, {"freejoint", "*", "2", "name", "group"}, {"geom", "*", "33", "name", "class", "type", "contype", "conaffinity", "condim", "group", "priority", "size", "material", "friction", "mass", "density", @@ -1573,6 +1574,9 @@ void mjXReader::OneJoint(XMLElement* elem, mjsJoint* pjoint) { ReadAttr(elem, "armature", 1, &pjoint->armature, text); ReadAttr(elem, "damping", 1, &pjoint->damping, text); ReadAttr(elem, "frictionloss", 1, &pjoint->frictionloss, text); + if (MapValue(elem, "actuatorgravcomp", &n, bool_map, 2)) { + pjoint->actgravcomp = (n==1); + } // read userdata if (ReadVector(elem, "user", userdata, text)) { diff --git a/src/xml/xml_native_writer.cc b/src/xml/xml_native_writer.cc index 9a20b95a..9f6d14f0 100644 --- a/src/xml/xml_native_writer.cc +++ b/src/xml/xml_native_writer.cc @@ -307,6 +307,7 @@ void mjXWriter::OneJoint(XMLElement* elem, mjCJoint* pjoint, mjCDef* def) { WriteAttr(elem, "range", 2, pjoint->range, def->joint.range); WriteAttrKey(elem, "actuatorfrclimited", TFAuto_map, 3, pjoint->actfrclimited, def->joint.actfrclimited); + WriteAttrKey(elem, "actuatorgravcomp", bool_map, 2, pjoint->actgravcomp, def->joint.actgravcomp); WriteAttr(elem, "actuatorfrcrange", 2, pjoint->actfrcrange, def->joint.actfrcrange); WriteAttr(elem, "margin", 1, &pjoint->margin, &def->joint.margin); WriteAttr(elem, "armature", 1, &pjoint->armature, &def->joint.armature); diff --git a/test/engine/engine_forward_test.cc b/test/engine/engine_forward_test.cc index 07af31bf..6f5087d9 100644 --- a/test/engine/engine_forward_test.cc +++ b/test/engine/engine_forward_test.cc @@ -765,6 +765,80 @@ TEST_F(ActuatorTest, ActuatorForceClamping) { mj_deleteModel(model); } +// Apply gravity compensation via actuators +TEST_F(ActuatorTest, ActuatorGravcomp) { + static constexpr char xml[] = R"( + + + + + + + + + + + + + + + + + + )"; + mjModel* model = LoadModelFromString(xml); + mjData* data = mj_makeData(model); + + mj_forward(model, data); + + // expect force clamping as specified in the model + EXPECT_EQ(data->actuator_force[0], 0); + EXPECT_EQ(data->qfrc_actuator[0], 2); + EXPECT_EQ(data->qfrc_passive[0], 0); + EXPECT_EQ(data->sensordata[0], 0); + EXPECT_EQ(data->sensordata[1], 2); + + // reduce gravity so gravcomp is not clamped + model->opt.gravity[2] = -1; + mj_forward(model, data); + EXPECT_EQ(data->actuator_force[0], 0); + EXPECT_EQ(data->qfrc_actuator[0], 1); + EXPECT_EQ(data->qfrc_passive[0], 0); + EXPECT_EQ(data->sensordata[0], 0); + EXPECT_EQ(data->sensordata[1], 1); + + // add control, see that it adds up + data->ctrl[0] = 0.5; + mj_forward(model, data); + EXPECT_EQ(data->actuator_force[0], 0.5); + EXPECT_EQ(data->qfrc_actuator[0], 1.5); + EXPECT_EQ(data->qfrc_passive[0], 0); + EXPECT_EQ(data->sensordata[0], 0.5); + EXPECT_EQ(data->sensordata[1], 1.5); + + // add larger control, expect clamping + data->ctrl[0] = 1.5; + mj_forward(model, data); + EXPECT_EQ(data->actuator_force[0], 1.5); + EXPECT_EQ(data->qfrc_actuator[0], 2); + EXPECT_EQ(data->qfrc_passive[0], 0); + EXPECT_EQ(data->sensordata[0], 1.5); + EXPECT_EQ(data->sensordata[1], 2); + + // disable actgravcomp, expect gravcomp as a passive force + model->jnt_actgravcomp[0] = 0; + mj_forward(model, data); + EXPECT_EQ(data->actuator_force[0], 1.5); + EXPECT_EQ(data->qfrc_actuator[0], 1.5); + EXPECT_EQ(data->qfrc_passive[0], 1); + EXPECT_EQ(data->sensordata[0], 1.5); + EXPECT_EQ(data->sensordata[1], 1.5); + + mj_deleteData(data); + mj_deleteModel(model); +} + // ----------------------- filterexact actuators ------------------------------- using FilterExactTest = MujocoTest; diff --git a/test/engine/testdata/actuation/refsite.xml b/test/engine/testdata/actuation/refsite.xml index eda8e284..7374d624 100644 --- a/test/engine/testdata/actuation/refsite.xml +++ b/test/engine/testdata/actuation/refsite.xml @@ -6,7 +6,7 @@ (e.g. 4 consecutive ball joints is not a realistic kinematic design) --> @@ -29,7 +29,7 @@ commands is achievable by individual joint actuators with the specified torque limits. See https://mujoco.readthedocs.io/en/latest//modeling.html#actuator-force-clamping --> - + @@ -37,19 +37,19 @@ - + - + - + - + diff --git a/unity/Runtime/Bindings/MjBindings.cs b/unity/Runtime/Bindings/MjBindings.cs index 278ed9e5..76a72196 100644 --- a/unity/Runtime/Bindings/MjBindings.cs +++ b/unity/Runtime/Bindings/MjBindings.cs @@ -5218,6 +5218,7 @@ public unsafe struct mjModel_ { public int* jnt_group; public byte* jnt_limited; public byte* jnt_actfrclimited; + public byte* jnt_actgravcomp; public double* jnt_solref; public double* jnt_solimp; public double* jnt_pos; From 5d26b50fcef9869477fc12b393fdffd6c122d8ae Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Thu, 28 Mar 2024 15:31:54 -0700 Subject: [PATCH 47/51] Remove native sensor noise sampling. PiperOrigin-RevId: 620075316 Change-Id: I6a0a1d63834e7c8bfd290f89d86fea791d794739 --- doc/XMLreference.rst | 6 -- doc/XMLschema.rst | 4 +- doc/changelog.rst | 36 ++++++++---- doc/includes/references.h | 7 +-- doc/modeling.rst | 7 ++- include/mujoco/mjmodel.h | 7 +-- introspect/enums.py | 7 +-- introspect/enums_test.py | 7 +-- python/mujoco/bindings_test.py | 8 +-- src/engine/engine_sensor.c | 86 +--------------------------- src/engine/engine_support.c | 1 - src/xml/xml_native_reader.cc | 5 +- src/xml/xml_native_writer.cc | 1 - unity/Runtime/Bindings/MjBindings.cs | 7 +-- 14 files changed, 54 insertions(+), 135 deletions(-) diff --git a/doc/XMLreference.rst b/doc/XMLreference.rst index 81bb0c3d..497bb654 100644 --- a/doc/XMLreference.rst +++ b/doc/XMLreference.rst @@ -2129,12 +2129,6 @@ from its default. When this flag is enabled, :ref:`mj_inverse` will interpret ``qacc`` as having been computed from the difference of two sequential velocities, and undo the above modification. -.. _option-flag-sensornoise: - -:at:`sensornoise`: :at-val:`[disable, enable], "disable"` - This flag enables the simulation of sensor noise. When disabled (which is the default) noise is not added to - sensordata, even if the sensors specify non-zero noise amplitudes. When enabled, zero-mean Gaussian noise is added to - the underlying deterministic sensor data. Its standard deviation is determined by the noise parameter of each sensor. .. _option-flag-multiccd: diff --git a/doc/XMLschema.rst b/doc/XMLschema.rst index 3327930d..5b516790 100644 --- a/doc/XMLschema.rst +++ b/doc/XMLschema.rst @@ -247,9 +247,9 @@ | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | | | | | :ref:`sensor` | :ref:`midphase` | :ref:`eulerdamp` | :ref:`override` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`energy` | :ref:`fwdinv` | :ref:`invdiscrete` | :ref:`sensornoise` | | +| | | | :ref:`energy` | :ref:`fwdinv` | :ref:`invdiscrete` | :ref:`multiccd` | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | -| | | | :ref:`multiccd` | :ref:`island` | | | | +| | | | :ref:`island` | | | | | | | | +-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+-----------------------------------------------------------------+ | +------------------------------------+----+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | mujoco |br| |L| | | .. table:: | diff --git a/doc/changelog.rst b/doc/changelog.rst index 027d3221..8e773523 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -7,29 +7,45 @@ Upcoming version (not yet released) General ^^^^^^^ -1. Added the :ref:`actuatorgravcomp` joint attribute. When enabled, gravity compensation +.. admonition:: Breaking API changes + :class: attention + + 1. Removed the ability to natively add noise to sensors. Note that the ``mjModel.sensor_noise`` field and + :ref:`corresponding attribute` are kept and now function as a convenient location for the user to save + standard-deviation information for their own use. This feature was removed because: + + - There was no mechanism to seed the randon noise generator. + - It was not thread-safe, even if seeding would have been provided, sampling on multiple threads would lead to + non-reproducible results. + - This feature was seen as overreach by the engine. Adding noise should be the user's responsibility. + - We are not aware of anyone who was actually using the feature. + + **Migration:** Add noise to sensor values yourself. + +2. Added the :ref:`actuatorgravcomp` joint attribute. When enabled, gravity compensation forces on the joint are treated as applied by actuators. See attribute documentation for more details. The example model `refsite.xml `__, which demostrates Cartesian actuation of an arm, has been updated to use this attribute. -2. Added support for gmsh format 2.2, as generated by e.g. `fTetwild `__. +3. Added support for gmsh format 2.2, as generated by e.g. `fTetwild `__. + MJX ^^^ -3. Improved performance of SAT for convex collisions. -4. Fixed bug for sphere/capsule-convex deep penetration. -5. Fixed bug where ``mjx.Data`` produced by ``mjx.put_data`` had different treedef than ``mjx.make_data``. -6. Throw an error for margin/gap for convex mesh collisions, since they are not supported. +4. Improved performance of SAT for convex collisions. +5. Fixed bug for sphere/capsule-convex deep penetration. +6. Fixed bug where ``mjx.Data`` produced by ``mjx.put_data`` had different treedef than ``mjx.make_data``. +7. Throw an error for margin/gap for convex mesh collisions, since they are not supported. Simulate ^^^^^^^^ -7. Fixed bug in order of enable flag strings. Before this change, using the simulate UI to toggle the - :ref:`invdiscrete` or :ref:`sensornoise` - flags would actually toggle the other flag. +8. Fixed bug in order of enable flag strings. Before this change, using the simulate UI to toggle the + :ref:`invdiscrete` or the (now removed) ``sensornoise`` flags would actually toggle the + other flag. Python bindings ^^^^^^^^^^^^^^^ -8. Added the ``mujoco.minimize`` Python module for nonlinear least-squares, designed for System Identification (sysID). +9. Added the ``mujoco.minimize`` Python module for nonlinear least-squares, designed for System Identification (sysID). The sysID tutorial is work in progress, but a pedagogical colab notebook with examples, including Inverse Kinematics, is available here: |ls_colab| diff --git a/doc/includes/references.h b/doc/includes/references.h index 8bb4ee1a..440b6e7d 100644 --- a/doc/includes/references.h +++ b/doc/includes/references.h @@ -426,12 +426,11 @@ typedef enum mjtEnableBit_ { // enable optional feature bitflags mjENBL_ENERGY = 1<<1, // energy computation mjENBL_FWDINV = 1<<2, // record solver statistics mjENBL_INVDISCRETE = 1<<3, // discrete-time inverse dynamics - mjENBL_SENSORNOISE = 1<<4, // add noise to sensor data // experimental features: - mjENBL_MULTICCD = 1<<5, // multi-point convex collision detection - mjENBL_ISLAND = 1<<6, // constraint island discovery + mjENBL_MULTICCD = 1<<4, // multi-point convex collision detection + mjENBL_ISLAND = 1<<5, // constraint island discovery - mjNENABLE = 7 // number of enable flags + mjNENABLE = 6 // number of enable flags } mjtEnableBit; typedef enum mjtJoint_ { // type of degree of freedom mjJNT_FREE = 0, // global position and orientation (quat) (7) diff --git a/doc/modeling.rst b/doc/modeling.rst index aa6d1693..36edf643 100644 --- a/doc/modeling.rst +++ b/doc/modeling.rst @@ -1057,9 +1057,10 @@ Here we describe the XML attributes common to all sensor types, so as to avoid r :at:`name`: :at-val:`string, optional` Name of the sensor. :at:`noise`: :at-val:`real, "0"` - The standard deviation of zero-mean Gaussian noise added to the sensor output, when the :at:`sensornoise` - attribute of :ref:`flag ` is enabled. Sensor noise respects the sensor data type: - quaternions and unit vectors remain normalized, non-negative quantities remain non-negative. + The standard deviation of the noise model of this sensor. In versions prior to 3.1.4, this would lead to noise being + added to the sensors. In release 3.1.4 this feature was removed, see :doc:`3.1.4 changelog ` for a + detailed justification. As of subsequent versions, this attrbute serves as a convenient location for saving standard + deviation information for later use. :at:`cutoff`: :at-val:`real, "0"` When this value is positive, it limits the absolute value of the sensor output. It is also used to normalize the sensor output in the sensor data plots in :ref:`simulate.cc `. diff --git a/include/mujoco/mjmodel.h b/include/mujoco/mjmodel.h index f4c480c6..2f0031e2 100644 --- a/include/mujoco/mjmodel.h +++ b/include/mujoco/mjmodel.h @@ -74,12 +74,11 @@ typedef enum mjtEnableBit_ { // enable optional feature bitflags mjENBL_ENERGY = 1<<1, // energy computation mjENBL_FWDINV = 1<<2, // record solver statistics mjENBL_INVDISCRETE = 1<<3, // discrete-time inverse dynamics - mjENBL_SENSORNOISE = 1<<4, // add noise to sensor data // experimental features: - mjENBL_MULTICCD = 1<<5, // multi-point convex collision detection - mjENBL_ISLAND = 1<<6, // constraint island discovery + mjENBL_MULTICCD = 1<<4, // multi-point convex collision detection + mjENBL_ISLAND = 1<<5, // constraint island discovery - mjNENABLE = 7 // number of enable flags + mjNENABLE = 6 // number of enable flags } mjtEnableBit; diff --git a/introspect/enums.py b/introspect/enums.py index a1fab80a..c2efcc25 100644 --- a/introspect/enums.py +++ b/introspect/enums.py @@ -54,10 +54,9 @@ ENUMS: Mapping[str, EnumDecl] = dict([ ('mjENBL_ENERGY', 2), ('mjENBL_FWDINV', 4), ('mjENBL_INVDISCRETE', 8), - ('mjENBL_SENSORNOISE', 16), - ('mjENBL_MULTICCD', 32), - ('mjENBL_ISLAND', 64), - ('mjNENABLE', 7), + ('mjENBL_MULTICCD', 16), + ('mjENBL_ISLAND', 32), + ('mjNENABLE', 6), ]), )), ('mjtJoint', diff --git a/introspect/enums_test.py b/introspect/enums_test.py index 3580d4c1..fe1981a9 100644 --- a/introspect/enums_test.py +++ b/introspect/enums_test.py @@ -42,10 +42,9 @@ class EnumsTest(absltest.TestCase): ('mjENBL_ENERGY', 1<<1), ('mjENBL_FWDINV', 1<<2), ('mjENBL_INVDISCRETE', 1<<3), - ('mjENBL_SENSORNOISE', 1<<4), - ('mjENBL_MULTICCD', 1<<5), - ('mjENBL_ISLAND', 1<<6), - ('mjNENABLE', 7))) + ('mjENBL_MULTICCD', 1<<4), + ('mjENBL_ISLAND', 1<<5), + ('mjNENABLE', 6))) # values mostly increment by one with occasional overrides def test_mjtGeom(self): # pylint: disable=invalid-name diff --git a/python/mujoco/bindings_test.py b/python/mujoco/bindings_test.py index 4a1da339..ea2e8f7c 100644 --- a/python/mujoco/bindings_test.py +++ b/python/mujoco/bindings_test.py @@ -623,7 +623,7 @@ class MuJoCoBindingsTest(parameterized.TestCase): self.assertEqual(struct, struct2) self.assertNotEqual(struct, 3) - self.assertNotEqual(struct, None) + self.assertIsNotNone(struct) # mutable structs shouldn't declare __hash__ with self.assertRaises(TypeError): @@ -705,7 +705,8 @@ class MuJoCoBindingsTest(parameterized.TestCase): # Check that the output argument must have the correct dtype. with self.assertRaises(TypeError): - mujoco.mju_rotVecQuat(vec, quat, res=np.zeros(3, int)) + res = np.zeros(3, np.int32) + mujoco.mju_rotVecQuat(res, vec, quat) def test_getsetstate(self): # pylint: disable=invalid-name mujoco.mj_step(self.model, self.data) @@ -850,8 +851,7 @@ Euler integrator, semi-implicit in velocity. self.assertEqual(mujoco.mjtEnableBit.mjENBL_OVERRIDE, 1<<0) self.assertEqual(mujoco.mjtEnableBit.mjENBL_ENERGY, 1<<1) self.assertEqual(mujoco.mjtEnableBit.mjENBL_FWDINV, 1<<2) - self.assertEqual(mujoco.mjtEnableBit.mjENBL_SENSORNOISE, 1<<4) - self.assertEqual(mujoco.mjtEnableBit.mjNENABLE, 7) + self.assertEqual(mujoco.mjtEnableBit.mjNENABLE, 6) self.assertEqual(mujoco.mjtGeom.mjGEOM_PLANE, 0) self.assertEqual(mujoco.mjtGeom.mjGEOM_HFIELD, 1) self.assertEqual(mujoco.mjtGeom.mjGEOM_SPHERE, 2) diff --git a/src/engine/engine_sensor.c b/src/engine/engine_sensor.c index 0e7be718..e1758260 100644 --- a/src/engine/engine_sensor.c +++ b/src/engine/engine_sensor.c @@ -32,78 +32,9 @@ #include "engine/engine_util_spatial.h" + //-------------------------------- utility --------------------------------------------------------- -// add sensor noise after each stage -static void add_noise(const mjModel* m, mjData* d, mjtStage stage) { - int adr, dim; - mjtNum rnd[4], noise, quat[4], res[4]; - - // process sensors matching stage and having positive noise - for (int i=0; i < m->nsensor; i++) { - if (m->sensor_needstage[i] == stage && m->sensor_noise[i] > 0) { - // get sensor info - adr = m->sensor_adr[i]; - dim = m->sensor_dim[i]; - noise = m->sensor_noise[i]; - - // real or positive: add noise directly, with clamp for positive - if (m->sensor_datatype[i] == mjDATATYPE_REAL || - m->sensor_datatype[i] == mjDATATYPE_POSITIVE) { - for (int j=0; j < dim; j++) { - // get random numbers; use only the first one - rnd[0] = mju_standardNormal(rnd+1); - - // positive - if (m->sensor_datatype[i] == mjDATATYPE_POSITIVE) { - // add noise only if positive, keep it positive - if (d->sensordata[adr+j] > 0) { - d->sensordata[adr+j] = mju_max(0, d->sensordata[adr+j]+rnd[0]*noise); - } - } - - // real - else { - d->sensordata[adr+j] += rnd[0]*noise; - } - } - } - - // axis or quat: rotate around random axis by random angle - else { - // get four random numbers - rnd[0] = mju_standardNormal(rnd+1); - rnd[2] = mju_standardNormal(rnd+3); - - // scale angle, normalize axis, make quaternion - rnd[0] *= noise; - mju_normalize3(rnd+1); - mju_axisAngle2Quat(quat, rnd+1, rnd[0]); - - // axis - if (m->sensor_datatype[i] == mjDATATYPE_AXIS) { - // apply quaternion rotation to axis, assign - mju_rotVecQuat(res, d->sensordata+adr, quat); - mju_copy3(d->sensordata+adr, res); - } - - // quaternion - else if (m->sensor_datatype[i] == mjDATATYPE_QUATERNION) { - // apply quaternion rotation to quaternion, assign - mju_mulQuat(d->sensordata+adr, d->sensordata+adr, quat); - } - - // unknown datatype - else { - mjERROR("unknown datatype in sensor %d", i); - } - } - } - } -} - - - // apply cutoff after each stage static void apply_cutoff(const mjModel* m, mjData* d, mjtStage stage) { // process sensors matching stage and having positive cutoff @@ -442,11 +373,6 @@ void mj_sensorPos(const mjModel* m, mjData* d) { mjcb_sensor(m, d, mjSTAGE_POS); } - // add noise if enabled - if (mjENABLED(mjENBL_SENSORNOISE)) { - add_noise(m, d, mjSTAGE_POS); - } - // compute plugin sensor values if (m->nplugin) { const int nslot = mjp_pluginCount(); @@ -623,11 +549,6 @@ void mj_sensorVel(const mjModel* m, mjData* d) { mjcb_sensor(m, d, mjSTAGE_VEL); } - // add noise if enabled - if (mjENABLED(mjENBL_SENSORNOISE)) { - add_noise(m, d, mjSTAGE_VEL); - } - // trigger computation of plugins if (m->nplugin) { const int nslot = mjp_pluginCount(); @@ -839,11 +760,6 @@ void mj_sensorAcc(const mjModel* m, mjData* d) { mjcb_sensor(m, d, mjSTAGE_ACC); } - // add noise if enabled - if (mjENABLED(mjENBL_SENSORNOISE)) { - add_noise(m, d, mjSTAGE_ACC); - } - // trigger computation of plugins if (m->nplugin) { const int nslot = mjp_pluginCount(); diff --git a/src/engine/engine_support.c b/src/engine/engine_support.c index 5deb1e72..1c3b928f 100644 --- a/src/engine/engine_support.c +++ b/src/engine/engine_support.c @@ -67,7 +67,6 @@ const char* mjENABLESTRING[mjNENABLE] = { "Energy", "Fwdinv", "InvDiscrete", - "Sensornoise", "MultiCCD", "Island" }; diff --git a/src/xml/xml_native_reader.cc b/src/xml/xml_native_reader.cc index 11811c2b..55e02d03 100644 --- a/src/xml/xml_native_reader.cc +++ b/src/xml/xml_native_reader.cc @@ -101,10 +101,10 @@ const char* MJCF[nMJCF][mjXATTRNUM] = { "solver", "iterations", "ls_iterations", "noslip_iterations", "mpr_iterations", "sdf_iterations", "sdf_initpoints", "actuatorgroupdisable"}, {"<"}, - {"flag", "?", "22", "constraint", "equality", "frictionloss", "limit", "contact", + {"flag", "?", "21", "constraint", "equality", "frictionloss", "limit", "contact", "passive", "gravity", "clampctrl", "warmstart", "filterparent", "actuation", "refsafe", "sensor", "midphase", "eulerdamp", - "override", "energy", "fwdinv", "invdiscrete", "sensornoise", "multiccd", "island"}, + "override", "energy", "fwdinv", "invdiscrete", "multiccd", "island"}, {">"}, {"size", "*", "14", "memory", "njmax", "nconmax", "nstack", "nuserdata", "nkey", @@ -1091,7 +1091,6 @@ void mjXReader::Option(XMLElement* section, mjOption* opt) { READENBL("energy", mjENBL_ENERGY) READENBL("fwdinv", mjENBL_FWDINV) READENBL("invdiscrete", mjENBL_INVDISCRETE) - READENBL("sensornoise", mjENBL_SENSORNOISE) READENBL("multiccd", mjENBL_MULTICCD) READENBL("island", mjENBL_ISLAND) #undef READENBL diff --git a/src/xml/xml_native_writer.cc b/src/xml/xml_native_writer.cc index 9f6d14f0..c70ee22b 100644 --- a/src/xml/xml_native_writer.cc +++ b/src/xml/xml_native_writer.cc @@ -938,7 +938,6 @@ void mjXWriter::Option(XMLElement* root) { WRITEENBL("energy", mjENBL_ENERGY) WRITEENBL("fwdinv", mjENBL_FWDINV) WRITEENBL("invdiscrete", mjENBL_INVDISCRETE) - WRITEENBL("sensornoise", mjENBL_SENSORNOISE) WRITEENBL("multiccd", mjENBL_MULTICCD) WRITEENBL("island", mjENBL_ISLAND) #undef WRITEENBL diff --git a/unity/Runtime/Bindings/MjBindings.cs b/unity/Runtime/Bindings/MjBindings.cs index 76a72196..4f7b7698 100644 --- a/unity/Runtime/Bindings/MjBindings.cs +++ b/unity/Runtime/Bindings/MjBindings.cs @@ -164,10 +164,9 @@ public enum mjtEnableBit : int{ mjENBL_ENERGY = 2, mjENBL_FWDINV = 4, mjENBL_INVDISCRETE = 8, - mjENBL_SENSORNOISE = 16, - mjENBL_MULTICCD = 32, - mjENBL_ISLAND = 64, - mjNENABLE = 7, + mjENBL_MULTICCD = 16, + mjENBL_ISLAND = 32, + mjNENABLE = 6, } public enum mjtJoint : int{ mjJNT_FREE = 0, From b85f419fcbdd111760499126ed36f1723655d9e4 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Thu, 28 Mar 2024 20:59:19 -0700 Subject: [PATCH 48/51] Add video with clips from least-squares tutorial to docs. PiperOrigin-RevId: 620144313 Change-Id: I79faa6a1446e9e6c88e16a238029f45c518c16d1 --- doc/changelog.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/changelog.rst b/doc/changelog.rst index 8e773523..126b62e1 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -45,9 +45,15 @@ Simulate Python bindings ^^^^^^^^^^^^^^^ + +.. youtube:: xHDS0n5DpqM + :align: right + :width: 240px + 9. Added the ``mujoco.minimize`` Python module for nonlinear least-squares, designed for System Identification (sysID). The sysID tutorial is work in progress, but a pedagogical colab notebook with examples, including Inverse Kinematics, is available here: |ls_colab| + |br| The video on the right shows example clips from the tutorial. .. |ls_colab| image:: https://colab.research.google.com/assets/colab-badge.svg :target: https://colab.research.google.com/github/google-deepmind/mujoco/blob/main/python/least_squares.ipynb From 827b7a279247e2637b8bea15299e0652b950bb0c Mon Sep 17 00:00:00 2001 From: Nimrod Gileadi Date: Tue, 2 Apr 2024 03:02:04 -0700 Subject: [PATCH 49/51] Solver parameter docs improvements. - Correct the equation for penetration depth. The equation is tested in engine_core_constraint_test.cc. - Add a tip on scaling damping with stiffness. PiperOrigin-RevId: 621111712 Change-Id: I8fcc133cbc638ffef2d0ddf4e298ae402dda7b6a --- doc/modeling.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/modeling.rst b/doc/modeling.rst index 36edf643..490affa8 100644 --- a/doc/modeling.rst +++ b/doc/modeling.rst @@ -421,7 +421,7 @@ and the damping ratio is ignored. Equivalently, in the direct format, the :math: impedance is constant, then the penetration depth at rest is .. math:: - r = \au \cdot (1 - d) \cdot \text{stiffness} + r = \frac{\au (1 - d)}{\text{stiffness}} .. tip:: In the positive-value default format, the :math:`\text{timeconst}` parameter controls constraint **softness**. @@ -431,6 +431,9 @@ and the damping ratio is ignored. Equivalently, in the direct format, the :math: The negative-value "direct" format is more flexible, for example allowing for perfectly elastic collisions (:math:`\text{damping} = 0`). It is the recommended format for system identification. + A :math:`\text{dampratio}` of 1 in the positive-value format is equivalent to + :math:`\text{damping} = 2 \sqrt{ \text{stiffness} }` in the direct format. + .. _CContact: Contact parameters From 02a7a8dc11d9cf061a5638096d589e051e6a9a79 Mon Sep 17 00:00:00 2001 From: Nimrod Gileadi Date: Tue, 2 Apr 2024 06:10:36 -0700 Subject: [PATCH 50/51] Fix integer overflow in MSH loading PiperOrigin-RevId: 621151576 Change-Id: I33f44dcc5d1099502714b384d97c37fe95e72186 --- src/user/user_mesh.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/user/user_mesh.cc b/src/user/user_mesh.cc index cfed0213..1ffadf6c 100644 --- a/src/user/user_mesh.cc +++ b/src/user/user_mesh.cc @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include #include @@ -1293,6 +1294,12 @@ void mjCMesh::LoadMSH(mjResource* resource) { throw mjCError(this, "invalid sizes in MSH file '%s'", resource->name); } + if (nvert_ >= INT_MAX / sizeof(float) / 3 || + nnormal_ >= INT_MAX / sizeof(float) / 3 || + ntexcoord_ >= INT_MAX / sizeof(float) / 2 || + nface_ >= INT_MAX / sizeof(int) / 3) { + throw mjCError(this, "too large sizes in MSH file '%s'.", resource->name); + } // check file size if (buffer_sz != 4*sizeof(int) + 3*nvert_*sizeof(float) + 3*nnormal_*sizeof(float) + 2*ntexcoord_*sizeof(float) + 3*nface_*sizeof(int)) { From d7f131e08677828733df66ba95881e46e6e7c2a6 Mon Sep 17 00:00:00 2001 From: Baruch Tabanpour Date: Tue, 2 Apr 2024 09:48:42 -0700 Subject: [PATCH 51/51] Add ellipsoid plane. Co-authored-by: Alessio Quaglino PiperOrigin-RevId: 621208833 Change-Id: I270c1ae0cecd7dd2d9b41da4e4d0b6378b105aaf --- mjx/mujoco/mjx/_src/collision_driver.py | 2 ++ mjx/mujoco/mjx/_src/collision_driver_test.py | 23 ++++++++++++++++++++ mjx/mujoco/mjx/_src/collision_primitive.py | 14 ++++++++++++ 3 files changed, 39 insertions(+) diff --git a/mjx/mujoco/mjx/_src/collision_driver.py b/mjx/mujoco/mjx/_src/collision_driver.py index 8fa56612..f7cec040 100644 --- a/mjx/mujoco/mjx/_src/collision_driver.py +++ b/mjx/mujoco/mjx/_src/collision_driver.py @@ -33,6 +33,7 @@ from mujoco.mjx._src.collision_convex import plane_convex from mujoco.mjx._src.collision_convex import sphere_convex from mujoco.mjx._src.collision_primitive import capsule_capsule from mujoco.mjx._src.collision_primitive import plane_capsule +from mujoco.mjx._src.collision_primitive import plane_ellipsoid from mujoco.mjx._src.collision_primitive import plane_sphere from mujoco.mjx._src.collision_primitive import sphere_capsule from mujoco.mjx._src.collision_primitive import sphere_sphere @@ -48,6 +49,7 @@ _COLLISION_FUNC = { (GeomType.PLANE, GeomType.SPHERE): plane_sphere, (GeomType.PLANE, GeomType.CAPSULE): plane_capsule, (GeomType.PLANE, GeomType.BOX): plane_convex, + (GeomType.PLANE, GeomType.ELLIPSOID): plane_ellipsoid, (GeomType.PLANE, GeomType.MESH): plane_convex, (GeomType.SPHERE, GeomType.SPHERE): sphere_sphere, (GeomType.SPHERE, GeomType.CAPSULE): sphere_capsule, diff --git a/mjx/mujoco/mjx/_src/collision_driver_test.py b/mjx/mujoco/mjx/_src/collision_driver_test.py index acb52e12..c707a74f 100644 --- a/mjx/mujoco/mjx/_src/collision_driver_test.py +++ b/mjx/mujoco/mjx/_src/collision_driver_test.py @@ -198,6 +198,29 @@ class SphereCollisionTest(parameterized.TestCase): _assert_attr_eq(dx.contact, d.contact, field.name, 'vertex_center', 1e-4) +class EllipsoidCollisionTest(parameterized.TestCase): + + _ELLIPSOID_PLANE = """ + + + + + + + + + + """ + + def test_plane_ellipsoid(self): + """Tests ellipsoid plane contact.""" + d, dx = _collide(self._ELLIPSOID_PLANE) + self.assertLess(dx.contact.dist[0], 0) + for field in dataclasses.fields(Contact): + _assert_attr_eq( + dx.contact, d.contact, field.name, 'ellipsoid-plane', 1e-5) + + class CapsuleCollisionTest(parameterized.TestCase): _CAP_PLANE = """ diff --git a/mjx/mujoco/mjx/_src/collision_primitive.py b/mjx/mujoco/mjx/_src/collision_primitive.py index 8c2dd529..a6fe5132 100644 --- a/mjx/mujoco/mjx/_src/collision_primitive.py +++ b/mjx/mujoco/mjx/_src/collision_primitive.py @@ -65,6 +65,19 @@ def plane_capsule(plane: GeomInfo, cap: GeomInfo) -> Contact: return jax.tree_map(lambda *x: jp.concatenate(x), *contacts) +def plane_ellipsoid(plane: GeomInfo, ellipsoid: GeomInfo) -> Contact: + """Calculates one contact between an ellipsoid and a plane.""" + n = plane.mat[:, 2] + size = ellipsoid.size + sphere_support = -math.normalize((ellipsoid.mat.T @ n) * size) + pos = ellipsoid.pos + ellipsoid.mat @ (sphere_support * size) + dist = jp.dot(n, pos - plane.pos) + pos = pos - n * dist * 0.5 + return jax.tree_map( + lambda x: jp.expand_dims(x, axis=0), (dist, pos, math.make_frame(n)) + ) + + def _sphere_sphere( pos1: jax.Array, radius1: jax.Array, pos2: jax.Array, radius2: jax.Array ) -> Contact: @@ -121,6 +134,7 @@ def capsule_capsule(cap1: GeomInfo, cap2: GeomInfo) -> Contact: # store ncon as function attributes plane_sphere.ncon = 1 plane_capsule.ncon = 2 +plane_ellipsoid.ncon = 1 sphere_sphere.ncon = 1 sphere_capsule.ncon = 1 capsule_capsule.ncon = 1