1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 //    names, trademarks, service marks, or product names of the Licensor
11 //    and its affiliates, except as required to comply with Section 4(c) of
12 //    the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 //     http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 
25 #include "pxr/pxr.h"
26 #include "pxr/base/gf/lineSeg.h"
27 #include "pxr/base/gf/math.h"
28 #include "pxr/base/gf/ostreamHelpers.h"
29 
30 #include "pxr/base/tf/type.h"
31 
32 #include <ostream>
33 
34 PXR_NAMESPACE_OPEN_SCOPE
35 
36 // CODE_COVERAGE_OFF_GCOV_BUG
TF_REGISTRY_FUNCTION(TfType)37 TF_REGISTRY_FUNCTION(TfType) {
38     TfType::Define<GfLineSeg>();
39 }
40 // CODE_COVERAGE_ON_GCOV_BUG
41 
42 GfVec3d
FindClosestPoint(const GfVec3d & point,double * t) const43 GfLineSeg::FindClosestPoint(const GfVec3d &point, double *t) const
44 {
45     // Find the parametric distance, lt, of the closest point on the line
46     // and then clamp lt to be on the line segment.
47 
48     double lt;
49     if ( _length == 0.0 )
50     {
51         lt = 0.0;
52     }
53     else
54     {
55         _line.FindClosestPoint( point, &lt );
56 
57         lt = GfClamp( lt / _length, 0, 1 );
58     }
59 
60     if ( t )
61 	*t = lt;
62 
63     return GetPoint( lt );
64 }
65 
66 bool
GfFindClosestPoints(const GfLine & line,const GfLineSeg & seg,GfVec3d * p1,GfVec3d * p2,double * t1,double * t2)67 GfFindClosestPoints( const GfLine &line, const GfLineSeg &seg,
68 		     GfVec3d *p1, GfVec3d *p2,
69 		     double *t1, double *t2 )
70 {
71     GfVec3d cp1, cp2;
72     double lt1, lt2;
73     if ( !GfFindClosestPoints( line, seg._line,  &cp1, &cp2, &lt1, &lt2 ) )
74 	return false;
75 
76     lt2 = GfClamp( lt2 / seg._length, 0, 1 );
77     cp2 = seg.GetPoint( lt2 );
78 
79     // If we clamp the line segment, change the rayPoint to be
80     // the closest point on the ray to the clamped point.
81     if (lt2 <= 0 || lt2 >= 1){
82         cp1 = line.FindClosestPoint(cp2, &lt1);
83     }
84 
85     if ( p1 )
86 	*p1 = cp1;
87 
88     if ( p2 )
89         *p2 = cp2;
90 
91     if ( t1 )
92 	*t1 = lt1;
93 
94     if ( t2 )
95 	*t2 = lt2;
96 
97     return true;
98 }
99 
100 
101 bool
GfFindClosestPoints(const GfLineSeg & seg1,const GfLineSeg & seg2,GfVec3d * p1,GfVec3d * p2,double * t1,double * t2)102 GfFindClosestPoints( const GfLineSeg &seg1, const GfLineSeg &seg2,
103 		     GfVec3d *p1, GfVec3d *p2,
104 		     double *t1, double *t2 )
105 {
106     GfVec3d cp1, cp2;
107     double lt1, lt2;
108     if ( !GfFindClosestPoints( seg1._line, seg2._line,
109 			       &cp1, &cp2, &lt1, &lt2 ) )
110 	return false;
111 
112     lt1 = GfClamp( lt1 / seg1._length, 0, 1 );
113 
114     lt2 = GfClamp( lt2 / seg2._length, 0, 1 );
115 
116     if ( p1 )
117 	*p1 = seg1.GetPoint( lt1 );
118 
119     if ( p2 )
120 	*p2 = seg2.GetPoint( lt2 );
121 
122     if ( t1 )
123 	*t1 = lt1;
124 
125     if ( t2 )
126 	*t2 = lt2;
127 
128     return true;
129 }
130 
131 std::ostream &
operator <<(std::ostream & out,const GfLineSeg & seg)132 operator<<(std::ostream &out, const GfLineSeg &seg)
133 {
134     return out << '('
135         << "point 1:" << Gf_OstreamHelperP(seg.GetPoint(0.0)) << ' '
136         << "point 2:" << Gf_OstreamHelperP(seg.GetPoint(1.0)) << ')';
137 }
138 
139 PXR_NAMESPACE_CLOSE_SCOPE
140