(*
Copyright by:
buildingSMART International Limited, 1996-2019

Any technical documentation made available by buildingSMART International Limited
is the copyrighted work of buildingSMART International Limited and is owned by the 
buildingSMART International Limited. It may be photocopied, used in software development, 
or translated into another computer language without prior written consent from 
buildingSMART International Limited provided that full attribution is given. 
Prior written consent is required if changes are made to the technical specification.

This material is delivered to you as is and buildingSMART International Limited makes 
no warranty of any kind with regard to it, including, but not limited to, the implied 
warranties as to its accuracy or fitness for a particular purpose. Any use of the 
technical documentation or the information contained therein is at the risk of the user. 
Documentation may include technical or other inaccuracies or typographical errors. 
buildingSMART International Limited shall not be liable for errors contained therein or 
for incidental consequential damages in connection with the furnishing, performance or use 
of the material. The information contained in this document is subject to change without notice.

Issue date:
Friday, July 26, 2019

*)

SCHEMA IFCGEOMETRICCONSTRAINTRESOURCE;

REFERENCE FROM IFCMEASURERESOURCE
(
  IfcLabel,
  IfcBoolean,
  IfcLengthMeasure
);

REFERENCE FROM IFCGEOMETRYRESOURCE
(
  IfcPoint,
  IfcBoundedCurve,
  IfcSurface,
  IfcCurve,
  IfcAxis2Placement,
  IfcLine,
  IfcConic,
  IfcPolyline,
  IfcTrimmedCurve,
  IfcCompositeCurve,
  IfcBSplineCurve,
  IfcDirection
);

REFERENCE FROM IFCTOPOLOGYRESOURCE
(
  IfcVertexPoint,
  IfcEdgeCurve,
  IfcFaceSurface,
  IfcClosedShell
);

REFERENCE FROM IFCGEOMETRICMODELRESOURCE
(
  IfcFaceBasedSurfaceModel,
  IfcSolidModel
);

REFERENCE FROM IFCPROFILERESOURCE
(
);

REFERENCE FROM IFCPRODUCTEXTENSION
(
  IfcGrid
);

REFERENCE FROM IFCKERNEL
(
  IfcProduct
);

REFERENCE FROM IFCPRESENTATIONAPPEARANCERESOURCE
(
  IfcNullStyle
);

TYPE IfcCurveOrEdgeCurve = SELECT
	(IfcBoundedCurve
	,IfcEdgeCurve);
END_TYPE;

TYPE IfcGridPlacementDirectionSelect = SELECT
	(IfcDirection
	,IfcVirtualGridIntersection);
END_TYPE;

TYPE IfcPointOrVertexPoint = SELECT
	(IfcPoint
	,IfcVertexPoint);
END_TYPE;

TYPE IfcSolidOrShell = SELECT
	(IfcClosedShell
	,IfcSolidModel);
END_TYPE;

TYPE IfcSurfaceOrFaceSurface = SELECT
	(IfcFaceBasedSurfaceModel
	,IfcFaceSurface
	,IfcSurface);
END_TYPE;

ENTITY IfcConnectionCurveGeometry
 SUBTYPE OF (IfcConnectionGeometry);
	CurveOnRelatingElement : IfcCurveOrEdgeCurve;
	CurveOnRelatedElement : OPTIONAL IfcCurveOrEdgeCurve;
END_ENTITY;

ENTITY IfcConnectionGeometry
 ABSTRACT SUPERTYPE OF (ONEOF
    (IfcConnectionCurveGeometry
    ,IfcConnectionPointGeometry
    ,IfcConnectionSurfaceGeometry
    ,IfcConnectionVolumeGeometry));
END_ENTITY;

ENTITY IfcConnectionPointEccentricity
 SUBTYPE OF (IfcConnectionPointGeometry);
	EccentricityInX : OPTIONAL IfcLengthMeasure;
	EccentricityInY : OPTIONAL IfcLengthMeasure;
	EccentricityInZ : OPTIONAL IfcLengthMeasure;
END_ENTITY;

ENTITY IfcConnectionPointGeometry
 SUPERTYPE OF (ONEOF
    (IfcConnectionPointEccentricity))
 SUBTYPE OF (IfcConnectionGeometry);
	PointOnRelatingElement : IfcPointOrVertexPoint;
	PointOnRelatedElement : OPTIONAL IfcPointOrVertexPoint;
END_ENTITY;

ENTITY IfcConnectionSurfaceGeometry
 SUBTYPE OF (IfcConnectionGeometry);
	SurfaceOnRelatingElement : IfcSurfaceOrFaceSurface;
	SurfaceOnRelatedElement : OPTIONAL IfcSurfaceOrFaceSurface;
END_ENTITY;

ENTITY IfcConnectionVolumeGeometry
 SUBTYPE OF (IfcConnectionGeometry);
	VolumeOnRelatingElement : IfcSolidOrShell;
	VolumeOnRelatedElement : OPTIONAL IfcSolidOrShell;
END_ENTITY;

ENTITY IfcGridAxis;
	AxisTag : OPTIONAL IfcLabel;
	AxisCurve : IfcCurve;
	SameSense : IfcBoolean;
 INVERSE
	PartOfW : SET [0:1] OF IfcGrid FOR WAxes;
	PartOfV : SET [0:1] OF IfcGrid FOR VAxes;
	PartOfU : SET [0:1] OF IfcGrid FOR UAxes;
	HasIntersections : SET [0:?] OF IfcVirtualGridIntersection FOR IntersectingAxes;
 WHERE
	WR1 : AxisCurve.Dim = 2;
	WR2 : (SIZEOF(PartOfU) = 1) XOR (SIZEOF(PartOfV) = 1) XOR (SIZEOF(PartOfW) = 1);
END_ENTITY;

ENTITY IfcGridPlacement
 SUBTYPE OF (IfcObjectPlacement);
	PlacementLocation : IfcVirtualGridIntersection;
	PlacementRefDirection : OPTIONAL IfcGridPlacementDirectionSelect;
END_ENTITY;

ENTITY IfcLocalPlacement
 SUBTYPE OF (IfcObjectPlacement);
	PlacementRelTo : OPTIONAL IfcObjectPlacement;
	RelativePlacement : IfcAxis2Placement;
 WHERE
	WR21 : IfcCorrectLocalPlacement(RelativePlacement, PlacementRelTo);
END_ENTITY;

ENTITY IfcObjectPlacement
 ABSTRACT SUPERTYPE OF (ONEOF
    (IfcGridPlacement
    ,IfcLocalPlacement));
 INVERSE
	PlacesObject : SET [0:?] OF IfcProduct FOR ObjectPlacement;
	ReferencedByPlacements : SET [0:?] OF IfcLocalPlacement FOR PlacementRelTo;
END_ENTITY;

ENTITY IfcVirtualGridIntersection;
	IntersectingAxes : LIST [2:2] OF IfcGridAxis;
	OffsetDistances : LIST [2:3] OF IfcLengthMeasure;
END_ENTITY;

FUNCTION IfcCorrectLocalPlacement
  (AxisPlacement:IfcAxis2Placement; 
   RelPlacement : IfcObjectPlacement):LOGICAL;

  IF (EXISTS(RelPlacement)) THEN
    IF ('IFCGEOMETRICCONSTRAINTRESOURCE.IFCGRIDPLACEMENT' IN TYPEOF(RelPlacement)) THEN
      RETURN(?);
    END_IF;
    IF ('IFCGEOMETRICCONSTRAINTRESOURCE.IFCLOCALPLACEMENT' IN TYPEOF(RelPlacement)) THEN
      IF ('IFCGEOMETRYRESOURCE.IFCAXIS2PLACEMENT2D' IN TYPEOF(AxisPlacement)) THEN
        RETURN(TRUE);
      END_IF;
      IF ('IFCGEOMETRYRESOURCE.IFCAXIS2PLACEMENT3D' IN TYPEOF(AxisPlacement)) THEN
        IF (RelPlacement\IfcLocalPlacement.RelativePlacement.Dim = 3) THEN
          RETURN(TRUE);
        ELSE
          RETURN(FALSE);
        END_IF;
      END_IF;
    END_IF;
  ELSE
    RETURN(TRUE);  
  END_IF;
  RETURN(?);
END_FUNCTION;

END_SCHEMA;
