Community
Civil 3D Customization
Welcome to Autodesk’s AutoCAD Civil 3D Forums. Share your knowledge, ask questions, and explore popular AutoCAD Civil 3D Customization topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Any plans to support adding points using point groups in API?

21 REPLIES 21
SOLVED
Reply
Message 1 of 22
soonhui
1379 Views, 21 Replies

Any plans to support adding points using point groups in API?

soonhui
Collaborator
Collaborator

Here it says not supported at the moment

 

But it would be good if it's supported, currently it's very annoying to be able to do only one way sync ( from Civil3D to my application) but not two way sync. Having the above API support will bridge this gap. 

##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

0 Likes

Any plans to support adding points using point groups in API?

Here it says not supported at the moment

 

But it would be good if it's supported, currently it's very annoying to be able to do only one way sync ( from Civil3D to my application) but not two way sync. Having the above API support will bridge this gap. 

##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

21 REPLIES 21
Message 2 of 22
soonhui
in reply to: soonhui

soonhui
Collaborator
Collaborator

@Tristone  here's another feature request that you can look into.

##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

0 Likes

@Tristone  here's another feature request that you can look into.

##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

Message 3 of 22
Jeff_M
in reply to: soonhui

Jeff_M
Consultant
Consultant

This seems to work just fine, C3D2018+. Is it not what you are looking for?

        public void tinpgtest()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var civdoc = CivilApplication.ActiveDocument;
            using (Transaction tr = doc.Database.TransactionManager.StartTransaction())
            {
                var surf = (TinSurface)tr.GetObject(TinSurface.Create(doc.Database, "PGTest"), OpenMode.ForWrite);
                surf.PointGroupsDefinition.AddPointGroup(civdoc.PointGroups["ForSurface"]);
                surf.Rebuild();
                tr.Commit();
            }
        }
Jeff_M, also a frequent Swamper
EESignature
0 Likes

This seems to work just fine, C3D2018+. Is it not what you are looking for?

        public void tinpgtest()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var civdoc = CivilApplication.ActiveDocument;
            using (Transaction tr = doc.Database.TransactionManager.StartTransaction())
            {
                var surf = (TinSurface)tr.GetObject(TinSurface.Create(doc.Database, "PGTest"), OpenMode.ForWrite);
                surf.PointGroupsDefinition.AddPointGroup(civdoc.PointGroups["ForSurface"]);
                surf.Rebuild();
                tr.Commit();
            }
        }
Jeff_M, also a frequent Swamper
EESignature
Message 4 of 22
Jeff_M
in reply to: soonhui

Jeff_M
Consultant
Consultant

It looks like the Developers Guide hasn't been updated in quite some time. It also shows "The ExtractContour() and ExtracBorder() methods exposed in the COM API are not yet available in the .NET API." which both have been available in.NET for many releases.

Jeff_M, also a frequent Swamper
EESignature
0 Likes

It looks like the Developers Guide hasn't been updated in quite some time. It also shows "The ExtractContour() and ExtracBorder() methods exposed in the COM API are not yet available in the .NET API." which both have been available in.NET for many releases.

Jeff_M, also a frequent Swamper
EESignature
Message 5 of 22
soonhui
in reply to: Jeff_M

soonhui
Collaborator
Collaborator

This is not all.

 

The main issue that I'm facing is how to populate the point group?

civdoc.PointGroups["ForSurface"]

If I want to put points into "ForSurface", how can I do it?

##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

0 Likes

This is not all.

 

The main issue that I'm facing is how to populate the point group?

civdoc.PointGroups["ForSurface"]

If I want to put points into "ForSurface", how can I do it?

##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

Message 6 of 22
Jeff_M
in reply to: soonhui

Jeff_M
Consultant
Consultant

Okay, that's not quite what you asked. However, to add points to a point group you need to use the PointGroupQuery and create the query string. See if this helps:

https://forums.autodesk.com/t5/civil-3d-customization/adding-points-to-point-group/m-p/8966612#M1695...

Jeff_M, also a frequent Swamper
EESignature
0 Likes

Okay, that's not quite what you asked. However, to add points to a point group you need to use the PointGroupQuery and create the query string. See if this helps:

https://forums.autodesk.com/t5/civil-3d-customization/adding-points-to-point-group/m-p/8966612#M1695...

Jeff_M, also a frequent Swamper
EESignature
Message 7 of 22
Jeff_M
in reply to: soonhui

Jeff_M
Consultant
Consultant

@soonhui which point property would you be using to assign the points to a group if you were to do it inside C3D? Include numbers matching? Raw description matching? Elevation matching? Here's a quick example.

        [CommandMethod("TIN_PG_TEST")]
        public void tinpgtest()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var civdoc = CivilApplication.ActiveDocument;
            using (Transaction tr = doc.Database.TransactionManager.StartTransaction())
            {
                var pg = (PointGroup)tr.GetObject(civdoc.PointGroups.Add("ForSurface"), OpenMode.ForWrite);
                var pgquery = (StandardPointGroupQuery)pg.GetQuery();
                pgquery.IncludeNumbers = "1000-1100";
                pgquery.IncludeRawDescriptions = "gnd*,conc*";
                pgquery.ExcludeRawDescriptions = "curb*";
                pg.SetQuery(pgquery);
                var surf = (TinSurface)tr.GetObject(TinSurface.Create(doc.Database, "PGTest"), OpenMode.ForWrite);
                surf.PointGroupsDefinition.AddPointGroup(pg.ObjectId);
                surf.Rebuild();
                tr.Commit();
            }
        }
Jeff_M, also a frequent Swamper
EESignature
0 Likes

@soonhui which point property would you be using to assign the points to a group if you were to do it inside C3D? Include numbers matching? Raw description matching? Elevation matching? Here's a quick example.

        [CommandMethod("TIN_PG_TEST")]
        public void tinpgtest()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var civdoc = CivilApplication.ActiveDocument;
            using (Transaction tr = doc.Database.TransactionManager.StartTransaction())
            {
                var pg = (PointGroup)tr.GetObject(civdoc.PointGroups.Add("ForSurface"), OpenMode.ForWrite);
                var pgquery = (StandardPointGroupQuery)pg.GetQuery();
                pgquery.IncludeNumbers = "1000-1100";
                pgquery.IncludeRawDescriptions = "gnd*,conc*";
                pgquery.ExcludeRawDescriptions = "curb*";
                pg.SetQuery(pgquery);
                var surf = (TinSurface)tr.GetObject(TinSurface.Create(doc.Database, "PGTest"), OpenMode.ForWrite);
                surf.PointGroupsDefinition.AddPointGroup(pg.ObjectId);
                surf.Rebuild();
                tr.Commit();
            }
        }
Jeff_M, also a frequent Swamper
EESignature
Message 8 of 22
soonhui
in reply to: Jeff_M

soonhui
Collaborator
Collaborator

Thank you for your help. Maybe I didn't specify my question very well, here's another attempt.

 

The idea is that I will need to create not just TinSurface and the relevant PointGroups that are attached to it, I also need to create Points that I will add to PointGroup ( no, those Points aren't there for me to select and add in the first place; they are from another source and not inside the initial drawing file).

 

From the example that I can see, we can create TinSurface, can add PointGroup to the Surface, and can select and add Points into the PointGroup via PointGroupQuery.

 

But how can we create the Points?

##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

0 Likes

Thank you for your help. Maybe I didn't specify my question very well, here's another attempt.

 

The idea is that I will need to create not just TinSurface and the relevant PointGroups that are attached to it, I also need to create Points that I will add to PointGroup ( no, those Points aren't there for me to select and add in the first place; they are from another source and not inside the initial drawing file).

 

From the example that I can see, we can create TinSurface, can add PointGroup to the Surface, and can select and add Points into the PointGroup via PointGroupQuery.

 

But how can we create the Points?

##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

Message 9 of 22
Jeff_M
in reply to: soonhui

Jeff_M
Consultant
Consultant

Look at the CogoPointCollection.  It has multiple Add methods as well as multiple Import methods.

So Add or Import your points, create the PointGroup, Create the Surface.

 

Or, add the point file directly to the surface using the PointFileDefinition property of the surface. No need to add the points to the dwg.

Jeff_M, also a frequent Swamper
EESignature
0 Likes

Look at the CogoPointCollection.  It has multiple Add methods as well as multiple Import methods.

So Add or Import your points, create the PointGroup, Create the Surface.

 

Or, add the point file directly to the surface using the PointFileDefinition property of the surface. No need to add the points to the dwg.

Jeff_M, also a frequent Swamper
EESignature
Message 10 of 22
soonhui
in reply to: Jeff_M

soonhui
Collaborator
Collaborator
Accepted solution

Thank you @Jeff_M ,

 

I just found out that aren't we complicating ourselves? There is a TinSurface.AddVertices method that we can use. My code here:

 

 

     public void AddSurfaces(Point3d[] points)
        {
           
           
            ObjectId surfaceID = ObjectId.Null;
            
            using (Transaction tr = ActiveACADDocument.Database.TransactionManager.StartTransaction())
            {
               
                var surf = (TinSurface)tr.GetObject(TinSurface.Create(ActiveACADDocument.Database, "PGTest"), OpenMode.ForWrite);
                surfaceID = surf.ObjectId;
                surf.AddVertices(new Point3dCollection(points));
                surf.Rebuild();
                tr.Commit();
            }

            using (Transaction ts = ActiveACADDocument.Database.TransactionManager.StartTransaction())
            {
                var surface = ts.GetObject(surfaceID, OpenMode.ForRead) as TinSurface;
                var spCollection = new List<Point3d>();
                foreach (var vertex in surface.Vertices)
                {
                    spCollection.Add(vertex.Location);
                }

            }
        }

 

 

The point list that is being added and extracted from the TinSurface seems to agree quite well...

 

Anything I miss?

##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

0 Likes

Thank you @Jeff_M ,

 

I just found out that aren't we complicating ourselves? There is a TinSurface.AddVertices method that we can use. My code here:

 

 

     public void AddSurfaces(Point3d[] points)
        {
           
           
            ObjectId surfaceID = ObjectId.Null;
            
            using (Transaction tr = ActiveACADDocument.Database.TransactionManager.StartTransaction())
            {
               
                var surf = (TinSurface)tr.GetObject(TinSurface.Create(ActiveACADDocument.Database, "PGTest"), OpenMode.ForWrite);
                surfaceID = surf.ObjectId;
                surf.AddVertices(new Point3dCollection(points));
                surf.Rebuild();
                tr.Commit();
            }

            using (Transaction ts = ActiveACADDocument.Database.TransactionManager.StartTransaction())
            {
                var surface = ts.GetObject(surfaceID, OpenMode.ForRead) as TinSurface;
                var spCollection = new List<Point3d>();
                foreach (var vertex in surface.Vertices)
                {
                    spCollection.Add(vertex.Location);
                }

            }
        }

 

 

The point list that is being added and extracted from the TinSurface seems to agree quite well...

 

Anything I miss?

##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

Message 11 of 22
Jeff_M
in reply to: soonhui

Jeff_M
Consultant
Consultant
If that dies what you need it to then I'd say all is well.
Jeff_M, also a frequent Swamper
EESignature
0 Likes

If that dies what you need it to then I'd say all is well.
Jeff_M, also a frequent Swamper
EESignature
Message 12 of 22
Tristone
in reply to: soonhui

Tristone
Autodesk
Autodesk

@soonhui  I think @Jeff_M has explained very well about PointsCollection, PointsGroup, and how to add points to TinSurface.
The naming of PointsGroup(in product, not only in API) might be misleading a little bit, as it's not a real physical collection of cogo points. Instead, it's a logical group depending on how user define it by query builder. A cogo points can be part of multiple points group, so we only support adding cogo point through CogoPointCollection, but not PointGroup object. 

As you have found, to create Tin Surface,  you don't have to create cogo points objects unless you want those points are connected to other workflows. 

 



Tristone Hua
Software Development Manager
AEC-BID-Infrastructure
Autodesk, Inc.

0 Likes

@soonhui  I think @Jeff_M has explained very well about PointsCollection, PointsGroup, and how to add points to TinSurface.
The naming of PointsGroup(in product, not only in API) might be misleading a little bit, as it's not a real physical collection of cogo points. Instead, it's a logical group depending on how user define it by query builder. A cogo points can be part of multiple points group, so we only support adding cogo point through CogoPointCollection, but not PointGroup object. 

As you have found, to create Tin Surface,  you don't have to create cogo points objects unless you want those points are connected to other workflows. 

 



Tristone Hua
Software Development Manager
AEC-BID-Infrastructure
Autodesk, Inc.

Message 13 of 22
soonhui
in reply to: Tristone

soonhui
Collaborator
Collaborator

@Tristone ,

 

In that case, do you have any samples on how to make reference to CogoPointGroup fromSurface.PointGroupsDefinition

?

 

To me they are different ( and you can't refer to CogoPointGroup from Surface.PointGroupsDefinition, because their "source is different"; CivilDocument contains PointGroups and COGOPoints as separate properties, after all

##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

0 Likes

@Tristone ,

 

In that case, do you have any samples on how to make reference to CogoPointGroup fromSurface.PointGroupsDefinition

?

 

To me they are different ( and you can't refer to CogoPointGroup from Surface.PointGroupsDefinition, because their "source is different"; CivilDocument contains PointGroups and COGOPoints as separate properties, after all

##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

Message 14 of 22
Tristone
in reply to: soonhui

Tristone
Autodesk
Autodesk

@soonhui The point group in Surface.PointGroupsDefinition must be one of the point group objects in CivilDocumen
 Please refer to below sample code to get the point group from Surface.PointGroupsDefinition

            var surfaceId = CivilApplication.ActiveDocument.GetSurfaceIds()[0];
            using (Transaction tr = Application.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction())
            {
                var surfaceObject = surfaceId.GetObject(OpenMode.ForRead) as TinSurface;
                var pointGroupDefs = surfaceObject.PointGroupsDefinition;
                var addPointGroupOperation = pointGroupDefs[0];
                var pointGroupId = addPointGroupOperation.PointGroupId;
                var pointGroup = pointGroupId.GetObject(OpenMode.ForRead) as PointGroup;
            }


Tristone Hua
Software Development Manager
AEC-BID-Infrastructure
Autodesk, Inc.

0 Likes

@soonhui The point group in Surface.PointGroupsDefinition must be one of the point group objects in CivilDocumen
 Please refer to below sample code to get the point group from Surface.PointGroupsDefinition

            var surfaceId = CivilApplication.ActiveDocument.GetSurfaceIds()[0];
            using (Transaction tr = Application.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction())
            {
                var surfaceObject = surfaceId.GetObject(OpenMode.ForRead) as TinSurface;
                var pointGroupDefs = surfaceObject.PointGroupsDefinition;
                var addPointGroupOperation = pointGroupDefs[0];
                var pointGroupId = addPointGroupOperation.PointGroupId;
                var pointGroup = pointGroupId.GetObject(OpenMode.ForRead) as PointGroup;
            }


Tristone Hua
Software Development Manager
AEC-BID-Infrastructure
Autodesk, Inc.

Message 15 of 22
soonhui
in reply to: Tristone

soonhui
Collaborator
Collaborator

@Tristone ,

 

I'm well aware of your code sample but it's not doing ( enough of) what I want. You are not showing how we can add  Points to the PointGroup. Please read the previous discussion on this thread again. 

##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

0 Likes

@Tristone ,

 

I'm well aware of your code sample but it's not doing ( enough of) what I want. You are not showing how we can add  Points to the PointGroup. Please read the previous discussion on this thread again. 

##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

Message 16 of 22
Tristone
in reply to: soonhui

Tristone
Autodesk
Autodesk

@soonhui  Well , regarding "how we can add  Points to the PointGroup"
@Jeff_M has provided a good example code of including points to point group in the above thread.
Query builder is the key part (for both Civil GUI and API)to include desired points.
Standard Query is the most common one as shown in the sample codes. 
Instead of point ranges (for example "100-105"), you can also use a comma-separated list of point numbers.



Tristone Hua
Software Development Manager
AEC-BID-Infrastructure
Autodesk, Inc.

0 Likes

@soonhui  Well , regarding "how we can add  Points to the PointGroup"
@Jeff_M has provided a good example code of including points to point group in the above thread.
Query builder is the key part (for both Civil GUI and API)to include desired points.
Standard Query is the most common one as shown in the sample codes. 
Instead of point ranges (for example "100-105"), you can also use a comma-separated list of point numbers.



Tristone Hua
Software Development Manager
AEC-BID-Infrastructure
Autodesk, Inc.

Message 17 of 22
soonhui
in reply to: Tristone

soonhui
Collaborator
Collaborator

@Tristone ,

 

What if the points are not yet there? As far as I know the Point query only works if the points are available for selection and filtering. 

 

@Jeff_M  only provided examples on how to query the points to be added to a point group , he didn't provide examples on how to create the points if they are not there. He did suggest to use CogoPointCollection, but I doubt whether it's feasible because  CivilDocument contains PointGroups and COGOPoints as separate properties.

 

To prevent further confusion, maybe you can show me a complete example on how the below can be done? 

 

  1. Create points from an external source, say, a CSV file. 
  2. Add/remove those points to a point group. If the point group is not there, create it.
  3. Add the Point group to a TinSurface.
  4. If the external source is updated, how can the points in TinSurface be refreshed, and TinSurface be rebuilt. 
##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

0 Likes

@Tristone ,

 

What if the points are not yet there? As far as I know the Point query only works if the points are available for selection and filtering. 

 

@Jeff_M  only provided examples on how to query the points to be added to a point group , he didn't provide examples on how to create the points if they are not there. He did suggest to use CogoPointCollection, but I doubt whether it's feasible because  CivilDocument contains PointGroups and COGOPoints as separate properties.

 

To prevent further confusion, maybe you can show me a complete example on how the below can be done? 

 

  1. Create points from an external source, say, a CSV file. 
  2. Add/remove those points to a point group. If the point group is not there, create it.
  3. Add the Point group to a TinSurface.
  4. If the external source is updated, how can the points in TinSurface be refreshed, and TinSurface be rebuilt. 
##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

Message 18 of 22
Tristone
in reply to: soonhui

Tristone
Autodesk
Autodesk

@soonhui Attached is the example code of Cogo Point and PointGroup which is shipped with Civil 3D application. For 1,2 and 3 You should be able to find many sample sources under Civil installation folder.

If you search the "CogoPointCollectionImportPointsOptionsPointGroup()", you can find a example of importing and create point group.
For 4. Surface.Rebuid() should work.

Please have a try first.  





 



Tristone Hua
Software Development Manager
AEC-BID-Infrastructure
Autodesk, Inc.

0 Likes

@soonhui Attached is the example code of Cogo Point and PointGroup which is shipped with Civil 3D application. For 1,2 and 3 You should be able to find many sample sources under Civil installation folder.

If you search the "CogoPointCollectionImportPointsOptionsPointGroup()", you can find a example of importing and create point group.
For 4. Surface.Rebuid() should work.

Please have a try first.  





 



Tristone Hua
Software Development Manager
AEC-BID-Infrastructure
Autodesk, Inc.

Message 19 of 22
soonhui
in reply to: Tristone

soonhui
Collaborator
Collaborator

@Tristone ,

 

All the examples you have shown and pointed to me don't quite do specifically what I need-- they may do 1 or 2, but not the rest, and it doesn't appear that they can be easily generalized to do what I want.

 

Hopefully you can craft a sample that addresses directly the 4 requirements that I listed above. 

##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

0 Likes

@Tristone ,

 

All the examples you have shown and pointed to me don't quite do specifically what I need-- they may do 1 or 2, but not the rest, and it doesn't appear that they can be easily generalized to do what I want.

 

Hopefully you can craft a sample that addresses directly the 4 requirements that I listed above. 

##########

Ngu Soon Hui

##########

I'm the Benevolent Dictator for Life for MiTS Software.

Read more at here

Message 20 of 22
Jeff_M
in reply to: soonhui

Jeff_M
Consultant
Consultant

@soonhui wrote:

 

To prevent further confusion, maybe you can show me a complete example on how the below can be done? 

 

  1. Create points from an external source, say, a CSV file. 
  2. Add/remove those points to a point group. If the point group is not there, create it.
  3. Add the Point group to a TinSurface.
  4. If the external source is updated, how can the points in TinSurface be refreshed, and TinSurface be rebuilt. 

I'm not going to write the code for you. Here are the steps you need to take:

1. Create or Get the point group: https://help.autodesk.com/view/CIV3D/2022/ENU/?guid=450628d7-9b17-586d-b877-e67d50447dd9

or: CivDoc.PointGroups["Name"];

2. Get the CogoPointsCollection from the CivilDocument.

3. Import the PointFile to the point group: https://help.autodesk.com/view/CIV3D/2022/ENU/?guid=6c8517e7-03d9-8d1e-9d95-fcdefd7c5f01

4. Create the Surface, add the PointGroup, rebuild surface: I believe this example has already been shown

5.When the points need updating, Delete The points in the point group:  https://help.autodesk.com/view/CIV3D/2022/ENU/?guid=f0ba00c9-6b3e-27e2-18f3-aba125f99af3

6. Import the PointFile to the point group

7. Rebuild the surface

Jeff_M, also a frequent Swamper
EESignature


@soonhui wrote:

 

To prevent further confusion, maybe you can show me a complete example on how the below can be done? 

 

  1. Create points from an external source, say, a CSV file. 
  2. Add/remove those points to a point group. If the point group is not there, create it.
  3. Add the Point group to a TinSurface.
  4. If the external source is updated, how can the points in TinSurface be refreshed, and TinSurface be rebuilt. 

I'm not going to write the code for you. Here are the steps you need to take:

1. Create or Get the point group: https://help.autodesk.com/view/CIV3D/2022/ENU/?guid=450628d7-9b17-586d-b877-e67d50447dd9

or: CivDoc.PointGroups["Name"];

2. Get the CogoPointsCollection from the CivilDocument.

3. Import the PointFile to the point group: https://help.autodesk.com/view/CIV3D/2022/ENU/?guid=6c8517e7-03d9-8d1e-9d95-fcdefd7c5f01

4. Create the Surface, add the PointGroup, rebuild surface: I believe this example has already been shown

5.When the points need updating, Delete The points in the point group:  https://help.autodesk.com/view/CIV3D/2022/ENU/?guid=f0ba00c9-6b3e-27e2-18f3-aba125f99af3

6. Import the PointFile to the point group

7. Rebuild the surface

Jeff_M, also a frequent Swamper
EESignature

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Rail Community


Autodesk Design & Make Report